author | Oana Pop Rus <opoprus@mozilla.com> |
Mon, 07 Jan 2019 11:30:15 +0200 | |
changeset 452676 | 0dcf945b38719b8475b212acc59105c933067ca6 |
parent 452668 | 029414a7448afe97b06f3f5a9c96ceaae93c44e3 (current diff) |
parent 452675 | 00e735944f33227af38ce7af53282bb8fd213a61 (diff) |
child 452687 | df193b44f65ab8fe8b249d1690b95c752bf93bde |
child 452706 | 67d8b5c4732383c6e7e5329c403dc42fac97e1bb |
push id | 35325 |
push user | opoprus@mozilla.com |
push date | Mon, 07 Jan 2019 09:30:40 +0000 |
treeherder | mozilla-central@0dcf945b3871 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | merge |
milestone | 66.0a1 |
first release with | nightly linux32
0dcf945b3871
/
66.0a1
/
20190107093040
/
files
nightly linux64
0dcf945b3871
/
66.0a1
/
20190107093040
/
files
nightly mac
0dcf945b3871
/
66.0a1
/
20190107093040
/
files
nightly win32
0dcf945b3871
/
66.0a1
/
20190107093040
/
files
nightly win64
0dcf945b3871
/
66.0a1
/
20190107093040
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
66.0a1
/
20190107093040
/
pushlog to previous
nightly linux64
66.0a1
/
20190107093040
/
pushlog to previous
nightly mac
66.0a1
/
20190107093040
/
pushlog to previous
nightly win32
66.0a1
/
20190107093040
/
pushlog to previous
nightly win64
66.0a1
/
20190107093040
/
pushlog to previous
|
servo/components/style/gecko/global_style_data.rs | file | annotate | diff | comparison | revisions |
--- a/Cargo.lock +++ b/Cargo.lock @@ -1029,17 +1029,17 @@ dependencies = [ "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", "nsstring 0.1.0", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.20.0", + "selectors 0.21.0", "servo_arc 0.1.1", "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "style_traits 0.0.1", ] [[package]] name = "generic-array" @@ -1430,20 +1430,20 @@ source = "registry+https://github.com/ru dependencies = [ "cc 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lock_api" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ @@ -1461,17 +1461,17 @@ dependencies = [ [[package]] name = "malloc_size_of" version = "0.0.1" dependencies = [ "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)", "hashglobe 0.1.0", - "selectors 0.20.0", + "selectors 0.21.0", "servo_arc 0.1.1", "smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1825,28 +1825,28 @@ dependencies = [ [[package]] name = "ordermap" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "owning_ref" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "parking_lot_core" version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ @@ -2223,17 +2223,17 @@ source = "registry+https://github.com/ru dependencies = [ "proc-macro2 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "selectors" -version = "0.20.0" +version = "0.21.0" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2435,22 +2435,22 @@ dependencies = [ "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "new_debug_unreachable 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "nsstring 0.1.0", "num-derive 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.20.0", + "selectors 0.21.0", "servo_arc 0.1.1", "smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "style_derive 0.0.1", "style_traits 0.0.1", "thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2477,17 +2477,17 @@ name = "style_traits" version = "0.0.1" dependencies = [ "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cssparser 0.25.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.4 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", "malloc_size_of_derive 0.0.1", - "selectors 0.20.0", + "selectors 0.21.0", "servo_arc 0.1.1", ] [[package]] name = "stylo_tests" version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2495,17 +2495,17 @@ dependencies = [ "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "geckoservo 0.0.1", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "selectors 0.20.0", + "selectors 0.21.0", "size_of_test 0.0.1", "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", "style 0.0.1", "style_traits 0.0.1", ] [[package]] name = "syn" @@ -3303,17 +3303,17 @@ dependencies = [ "checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" "checksum libloading 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3ad660d7cb8c5822cd83d10897b0f1f1526792737a179e73896152f85b88c2" "checksum libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ea626d3bdf40a1c5aee3bcd4f40826970cae8d80a8fec934c82a63840094dcfe" "checksum libz-sys 1.0.16 (registry+https://github.com/rust-lang/crates.io-index)" = "3fdd64ef8ee652185674455c1d450b83cbc8ad895625d543b5324d923f82e4d8" "checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" "checksum lmdb-rkv 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "07d8d72d709440ac7a19b71e04fb66684ec7547b3831817872454b01fdaefe23" "checksum lmdb-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d5b392838cfe8858e86fac37cf97a0e8c55cc60ba0a18365cadc33092f128ce9" -"checksum lock_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54" +"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" "checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46f3c7359028b31999287dae4e5047ddfe90a23b7dca2282ce759b491080c99b" "checksum memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2ffa2c986de11a9df78620c01eeaaf27d94d3ff02bf81bfcca953102dd0c6ff" "checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" @@ -3334,17 +3334,17 @@ dependencies = [ "checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" "checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" "checksum object 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6cca6ad89d0801138cb4ef606908ae12d83edc4c790ef5178fc7b4c72d959e90" "checksum opaque-debug 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "51ecbcb821e1bd256d456fe858aaa7f380b63863eab2eb86eee1bd9f33dd6682" "checksum ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0015e9e8e28ee20c581cfbfe47c650cedeb9ed0721090e0b7ebb10b9cdbcc2" "checksum ordermap 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" -"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" +"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" "checksum parking_lot 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69376b761943787ebd5cc85a5bc95958651a22609c5c1c2b65de21786baec72b" "checksum parking_lot_core 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "4db1a8ccf734a7bce794cc19b3df06ed87ab2f3907036b693c68f56b4d4537fa" "checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" "checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356" "checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" "checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc" "checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f" "checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
--- a/build/sanitizers/lsan_suppressions.txt +++ b/build/sanitizers/lsan_suppressions.txt @@ -22,17 +22,17 @@ leak:pixman_implementation_lookup_compos leak:libfontconfig.so leak:GI___strdup # The symbol is really __GI___strdup, but if you have the leading _, it doesn't suppress it. # Bug 1078015 - If the process terminates during a PR_Sleep, LSAN detects a leak leak:PR_Sleep # Bug 1363976 - Stylo holds some global data alive forever. -leak:style::gecko::global_style_data +leak:style::global_style_data ### ### Many leaks only affect some test suites. The suite annotations are not checked. ### # Bug 979928 - WebRTC leaks in different mochitest suites. leak:NR_reg_init # nr_reg_local_init should be redundant with NR_reg_init, but on Aurora
--- a/devtools/client/netmonitor/test/browser.ini +++ b/devtools/client/netmonitor/test/browser.ini @@ -113,17 +113,17 @@ subsuite = clipboard [browser_net_cookies_sorted.js] skip-if = (verify && debug && os == 'win') [browser_net_copy_as_curl.js] subsuite = clipboard [browser_net_cors_requests.js] [browser_net_cyrillic-01.js] [browser_net_cyrillic-02.js] [browser_net_frame.js] -skip-if = (os == 'mac') # Bug 1479782 +skip-if = (os == 'mac') || (os == 'win' && os_version == '10.0') # Bug 1479782 [browser_net_header-docs.js] [browser_net_edit_resend_cancel.js] [browser_net_edit_resend_caret.js] [browser_net_edit_resend_with_filtering.js] [browser_net_edit_resend_xhr.js] [browser_net_filter-01.js] [browser_net_filter-02.js] [browser_net_filter-03.js]
--- a/servo/components/selectors/Cargo.toml +++ b/servo/components/selectors/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "selectors" -version = "0.20.0" +version = "0.21.0" authors = ["The Servo Project Developers"] documentation = "https://docs.rs/selectors/" description = "CSS Selectors matching for Rust" repository = "https://github.com/servo/servo" readme = "README.md" keywords = ["css", "selectors"] license = "MPL-2.0"
--- a/servo/components/selectors/matching.rs +++ b/servo/components/selectors/matching.rs @@ -256,20 +256,21 @@ where } debug_assert!(from_offset >= 1); debug_assert!(from_offset <= selector.len()); let iter = selector.iter_from(selector.len() - from_offset); debug_assert!( iter.clone().next().is_some() || - (from_offset != selector.len() && matches!( - selector.combinator_at_parse_order(from_offset), - Combinator::SlotAssignment | Combinator::PseudoElement - )), + (from_offset != selector.len() && + matches!( + selector.combinator_at_parse_order(from_offset), + Combinator::SlotAssignment | Combinator::PseudoElement + )), "Got the math wrong: {:?} | {:?} | {} {}", selector, selector.iter_raw_match_order().as_slice(), from_offset, start_offset ); for component in iter { @@ -449,21 +450,19 @@ where element.containing_shadow_host() }, Combinator::SlotAssignment => { debug_assert!( context.current_host.is_some(), "Should not be trying to match slotted rules in a non-shadow-tree context" ); - debug_assert!( - element - .assigned_slot() - .map_or(true, |s| s.is_html_slot_element()) - ); + debug_assert!(element + .assigned_slot() + .map_or(true, |s| s.is_html_slot_element())); let scope = context.current_host?; let mut current_slot = element.assigned_slot()?; while current_slot.containing_shadow_host().unwrap().opaque() != scope { current_slot = current_slot.assigned_slot()?; } Some(current_slot) }, Combinator::PseudoElement => element.pseudo_element_originating_element(), @@ -669,19 +668,19 @@ where F: FnMut(&E, ElementSelectorFlags), { debug_assert!(context.shared.is_nested() || !context.shared.in_negation()); match *selector { Component::Combinator(_) => unreachable!(), Component::Slotted(ref selector) => { // <slots> are never flattened tree slottables. - !element.is_html_slot_element() && element.assigned_slot().is_some() && context - .shared - .nest(|context| { + !element.is_html_slot_element() && + element.assigned_slot().is_some() && + context.shared.nest(|context| { matches_complex_selector(selector.iter(), element, context, flags_setter) }) }, Component::PseudoElement(ref pseudo) => { element.match_pseudo_element(pseudo, context.shared) }, Component::LocalName(ref local_name) => matches_local_name(element, local_name), Component::ExplicitUniversalType | Component::ExplicitAnyNamespace => true,
--- a/servo/components/selectors/parser.rs +++ b/servo/components/selectors/parser.rs @@ -444,27 +444,25 @@ where ) { return false; } }, AttributeInNoNamespace { ref local_name, never_matches, .. - } - if !never_matches => - { + } if !never_matches => { if !visitor.visit_attribute_selector( &NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()), local_name, local_name, ) { return false; } - } + }, AttributeOther(ref attr_selector) if !attr_selector.never_matches => { let empty_string; let namespace = match attr_selector.namespace() { Some(ns) => ns, None => { empty_string = crate::parser::namespace_empty_string::<Impl>(); NamespaceConstraint::Specific(&empty_string) }, @@ -1361,17 +1359,17 @@ where has_pseudo_element = has_pseudo; slotted = slot; }, None => { return Err(input.new_custom_error(if builder.has_combinators() { SelectorParseErrorKind::DanglingCombinator } else { SelectorParseErrorKind::EmptySelector - })) + })); }, }; if has_pseudo_element || slotted { break; } // Parse a combinator. @@ -1629,17 +1627,17 @@ where let local_name; input.skip_whitespace(); match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? { OptionalQName::None(t) => { return Err(input.new_custom_error( SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t), - )) + )); }, OptionalQName::Some(_, None) => unreachable!(), OptionalQName::Some(ns, Some(ln)) => { local_name = ln; namespace = match ns { QNamePrefix::ImplicitNoNamespace | QNamePrefix::ExplicitNoNamespace => None, QNamePrefix::ExplicitNamespace(prefix, url) => { Some(NamespaceConstraint::Specific((prefix, url))) @@ -1686,17 +1684,17 @@ where Ok(&Token::PrefixMatch) => AttrSelectorOperator::Prefix, // [foo*=bar] Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring, // [foo$=bar] Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix, Ok(t) => { return Err(location.new_custom_error( SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t.clone()), - )) + )); }, }; let value = match input.expect_ident_or_string() { Ok(t) => t.clone(), Err(BasicParseError { kind: BasicParseErrorKind::UnexpectedToken(t), location, @@ -1763,21 +1761,22 @@ enum AttributeFlags { } impl AttributeFlags { fn to_case_sensitivity(self, local_name: &str, have_namespace: bool) -> ParsedCaseSensitivity { match self { AttributeFlags::CaseSensitive => ParsedCaseSensitivity::ExplicitCaseSensitive, AttributeFlags::AsciiCaseInsensitive => ParsedCaseSensitivity::AsciiCaseInsensitive, AttributeFlags::CaseSensitivityDependsOnName => { - if !have_namespace && include!(concat!( - env!("OUT_DIR"), - "/ascii_case_insensitive_html_attributes.rs" - )) - .contains(local_name) + if !have_namespace && + include!(concat!( + env!("OUT_DIR"), + "/ascii_case_insensitive_html_attributes.rs" + )) + .contains(local_name) { ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument } else { ParsedCaseSensitivity::CaseSensitive } }, } } @@ -1956,17 +1955,17 @@ where let location = input.current_source_location(); // TODO(emilio): Functional pseudo-classes too? // We don't need it for now. let name = match input.next_including_whitespace()? { &Token::Ident(ref name) => name.clone(), t => { return Err(location - .new_custom_error(SelectorParseErrorKind::NoIdentForPseudo(t.clone()))) + .new_custom_error(SelectorParseErrorKind::NoIdentForPseudo(t.clone()))); }, }; let pseudo_class = P::parse_non_ts_pseudo_class(parser, location, name.clone())?; if !p.supports_pseudo_class(&pseudo_class) { return Err(input.new_custom_error( SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name), ));
--- a/servo/components/style/Cargo.toml +++ b/servo/components/style/Cargo.toml @@ -11,18 +11,17 @@ build = "build.rs" links = "for some reason the links key is required to pass data around between build scripts" [lib] name = "style" path = "lib.rs" doctest = false [features] -gecko = ["nsstring", "num_cpus", - "style_traits/gecko", "fallible/known_system_malloc"] +gecko = ["nsstring", "style_traits/gecko", "fallible/known_system_malloc"] use_bindgen = ["bindgen", "regex", "toml"] servo = ["serde", "style_traits/servo", "servo_atoms", "servo_config", "html5ever", "cssparser/serde", "encoding_rs", "malloc_size_of/servo", "arrayvec/use_union", "servo_url", "string_cache", "crossbeam-channel"] gecko_debug = [] [dependencies] app_units = "0.7" @@ -43,22 +42,22 @@ html5ever = {version = "0.22", optional itertools = "0.7.6" itoa = "0.4" lazy_static = "1" log = "0.4" malloc_size_of = { path = "../malloc_size_of" } malloc_size_of_derive = { path = "../malloc_size_of_derive" } matches = "0.1" nsstring = {path = "../../../xpcom/rust/nsstring/", optional = true} -num_cpus = {version = "1.1.0", optional = true} +num_cpus = {version = "1.1.0"} num-integer = "0.1" num-traits = "0.2" num-derive = "0.2" ordered-float = "1.0" -owning_ref = "0.3.3" +owning_ref = "0.4" parking_lot = "0.6" precomputed-hash = "0.1.1" rayon = "1" selectors = { path = "../selectors" } serde = {version = "1.0", optional = true, features = ["derive"]} servo_arc = { path = "../servo_arc" } servo_atoms = {path = "../atoms", optional = true} servo_config = {path = "../config", optional = true}
--- a/servo/components/style/attr.rs +++ b/servo/components/style/attr.rs @@ -1,24 +1,24 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Parsed representations of [DOM attributes][attr]. //! //! [attr]: https://dom.spec.whatwg.org/#interface-attr -use app_units::Au; use crate::properties::PropertyDeclarationBlock; use crate::shared_lock::Locked; use crate::str::str_join; use crate::str::{read_exponent, read_fraction, HTML_SPACE_CHARACTERS}; use crate::str::{read_numbers, split_commas, split_html_space_chars}; use crate::values::specified::Length; use crate::{Atom, LocalName, Namespace, Prefix}; +use app_units::Au; use cssparser::{self, Color, RGBA}; use euclid::num::Zero; use num_traits::ToPrimitive; use selectors::attr::AttrSelectorOperation; use servo_arc::Arc; use servo_url::ServoUrl; use std::str::FromStr;
--- a/servo/components/style/bloom.rs +++ b/servo/components/style/bloom.rs @@ -2,18 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! The style bloom filter is used as an optimization when matching deep //! descendant selectors. #![deny(missing_docs)] +use crate::dom::{SendElement, TElement}; use atomic_refcell::{AtomicRefCell, AtomicRefMut}; -use crate::dom::{SendElement, TElement}; use owning_ref::OwningHandle; use selectors::bloom::BloomFilter; use servo_arc::Arc; use smallvec::SmallVec; /// Bloom filters are large allocations, so we store them in thread-local storage /// such that they can be reused across style traversals. StyleBloom is responsible /// for ensuring that the bloom filter is zeroed when it is dropped.
--- a/servo/components/style/build_gecko.rs +++ b/servo/components/style/build_gecko.rs @@ -510,18 +510,17 @@ mod bindings { .handle_table_items("array-types", |builder, item| { let cpp_type = item["cpp-type"].as_str().unwrap(); let rust_type = item["rust-type"].as_str().unwrap(); builder.raw_line(format!( concat!( "pub type nsTArrayBorrowed_{}<'a> = ", "&'a mut ::gecko_bindings::structs::nsTArray<{}>;" ), - cpp_type, - rust_type + cpp_type, rust_type )) }) .handle_str_items("servo-immutable-borrow-types", |b, ty| b.borrowed_type(ty)) // Right now the only immutable borrow types are ones which we import // from the |structs| module. As such, we don't need to create an opaque // type with zero_size_type. If we ever introduce immutable borrow types // which _do_ need to be opaque, we'll need a separate mode. .handle_str_items("servo-borrow-types", |b, ty| b.mutable_borrowed_type(ty))
--- a/servo/components/style/context.rs +++ b/servo/components/style/context.rs @@ -1,15 +1,14 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! The context within which style is calculated. -use app_units::Au; #[cfg(feature = "servo")] use crate::animation::Animation; use crate::bloom::StyleBloom; use crate::data::{EagerPseudoStyles, ElementData}; #[cfg(feature = "servo")] use crate::dom::OpaqueNode; use crate::dom::{SendElement, TElement}; use crate::font_metrics::FontMetricsProvider; @@ -24,16 +23,17 @@ use crate::rule_tree::StrongRuleNode; use crate::selector_parser::{SnapshotMap, EAGER_PSEUDO_COUNT}; use crate::shared_lock::StylesheetGuards; use crate::sharing::StyleSharingCache; use crate::stylist::Stylist; use crate::thread_state::{self, ThreadState}; use crate::timer::Timer; use crate::traversal::DomTraversal; use crate::traversal_flags::TraversalFlags; +use app_units::Au; #[cfg(feature = "servo")] use crossbeam_channel::Sender; use euclid::Size2D; use euclid::TypedScale; use fxhash::FxHashMap; #[cfg(feature = "servo")] use parking_lot::RwLock; use selectors::matching::ElementSelectorFlags;
--- a/servo/components/style/custom_properties.rs +++ b/servo/components/style/custom_properties.rs @@ -429,17 +429,17 @@ fn parse_declaration_value_block<'i, 't> let mut token_start = input.position(); let mut token = match input.next_including_whitespace_and_comments() { // FIXME: remove clone() when borrows are non-lexical Ok(token) => token.clone(), Err(_) => { return Ok(( TokenSerializationType::nothing(), TokenSerializationType::nothing(), - )) + )); }, }; let first_token_type = token.serialization_type(); loop { macro_rules! nested { () => { input.parse_nested_block(|input| { parse_declaration_value_block(
--- a/servo/components/style/dom.rs +++ b/servo/components/style/dom.rs @@ -2,32 +2,32 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Types and traits used to access the DOM from style calculation. #![allow(unsafe_code)] #![deny(missing_docs)] -use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; use crate::applicable_declarations::ApplicableDeclarationBlock; #[cfg(feature = "gecko")] use crate::context::PostAnimationTasks; #[cfg(feature = "gecko")] use crate::context::UpdateAnimationsTasks; use crate::data::ElementData; use crate::element_state::ElementState; use crate::font_metrics::FontMetricsProvider; use crate::media_queries::Device; use crate::properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock}; use crate::selector_parser::{AttrValue, Lang, PseudoElement, SelectorImpl}; use crate::shared_lock::Locked; use crate::stylist::CascadeData; use crate::traversal_flags::TraversalFlags; use crate::{Atom, LocalName, Namespace, WeakAtom}; +use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; use selectors::matching::{ElementSelectorFlags, QuirksMode, VisitedHandlingMode}; use selectors::sink::Push; use selectors::Element as SelectorsElement; use servo_arc::{Arc, ArcBorrow}; use std::fmt; use std::fmt::Debug; use std::hash::Hash; use std::ops::Deref; @@ -37,20 +37,17 @@ use std::ops::Deref; /// performed on this node is to compare it to another opaque handle or to another /// OpaqueNode. /// /// Layout and Graphics use this to safely represent nodes for comparison purposes. /// Because the script task's GC does not trace layout, node data cannot be safely stored in layout /// data structures. Also, layout code tends to be faster when the DOM is not being accessed, for /// locality reasons. Using `OpaqueNode` enforces this invariant. #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] -#[cfg_attr( - feature = "servo", - derive(MallocSizeOf, Deserialize, Serialize) -)] +#[cfg_attr(feature = "servo", derive(MallocSizeOf, Deserialize, Serialize))] pub struct OpaqueNode(pub usize); impl OpaqueNode { /// Returns the address of this node, for debugging purposes. #[inline] pub fn id(&self) -> usize { self.0 }
--- a/servo/components/style/font_face.rs +++ b/servo/components/style/font_face.rs @@ -331,19 +331,20 @@ impl<'a> FontFace<'a> { .iter() .rev() .filter(|source| { if let Source::Url(ref url_source) = **source { let hints = &url_source.format_hints; // We support only opentype fonts and truetype is an alias for // that format. Sources without format hints need to be // downloaded in case we support them. - hints.is_empty() || hints - .iter() - .any(|hint| hint == "truetype" || hint == "opentype" || hint == "woff") + hints.is_empty() || + hints.iter().any(|hint| { + hint == "truetype" || hint == "opentype" || hint == "woff" + }) } else { true } }) .cloned() .collect(), ) }
--- a/servo/components/style/font_metrics.rs +++ b/servo/components/style/font_metrics.rs @@ -1,22 +1,22 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Access to font metrics from the style system. #![deny(missing_docs)] -use app_units::Au; use crate::context::SharedStyleContext; use crate::logical_geometry::WritingMode; use crate::media_queries::Device; use crate::properties::style_structs::Font; use crate::Atom; +use app_units::Au; /// Represents the font metrics that style needs from a font to compute the /// value of certain CSS units like `ex`. #[derive(Clone, Debug, PartialEq)] pub struct FontMetrics { /// The x-height of the font. pub x_height: Au, /// The zero advance. This is usually writing mode dependent
--- a/servo/components/style/gecko/conversions.rs +++ b/servo/components/style/gecko/conversions.rs @@ -5,36 +5,36 @@ //! This module contains conversion helpers between Servo and Gecko types //! Ideally, it would be in geckolib itself, but coherence //! forces us to keep the traits and implementations here //! //! FIXME(emilio): This file should generally just die. #![allow(unsafe_code)] -use app_units::Au; use crate::gecko::values::GeckoStyleCoordConvertible; use crate::gecko_bindings::bindings; use crate::gecko_bindings::structs::RawGeckoGfxMatrix4x4; use crate::gecko_bindings::structs::{self, nsStyleCoord_CalcValue}; use crate::gecko_bindings::structs::{nsStyleImage, nsresult, SheetType}; use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; use crate::stylesheets::{Origin, RulesMutateError}; use crate::values::computed::image::LineDirection; use crate::values::computed::transform::Matrix3D; use crate::values::computed::url::ComputedImageUrl; use crate::values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; use crate::values::computed::{Integer, LengthOrPercentage}; use crate::values::computed::{LengthOrPercentageOrAuto, NonNegativeLengthOrPercentageOrAuto}; use crate::values::computed::{Percentage, TextAlign}; -use crate::values::generics::NonNegative; use crate::values::generics::box_::VerticalAlign; use crate::values::generics::grid::{TrackListValue, TrackSize}; use crate::values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; use crate::values::generics::rect::Rect; +use crate::values::generics::NonNegative; +use app_units::Au; use std::f32::consts::PI; impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue { fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue { let has_percentage = other.percentage.is_some(); nsStyleCoord_CalcValue { mLength: other.unclamped_length().to_i32_au(), mPercent: other.percentage.map_or(0., |p| p.0), @@ -672,21 +672,21 @@ pub mod basic_shape { use crate::values::computed::border::{BorderCornerRadius, BorderRadius}; use crate::values::computed::length::LengthOrPercentage; use crate::values::computed::motion::OffsetPath; use crate::values::computed::position; use crate::values::computed::url::ComputedUrl; use crate::values::generics::basic_shape::{ BasicShape as GenericBasicShape, InsetRect, Polygon, }; - use crate::values::generics::NonNegative; use crate::values::generics::basic_shape::{Circle, Ellipse, Path, PolygonCoord}; use crate::values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource}; use crate::values::generics::border::BorderRadius as GenericBorderRadius; use crate::values::generics::rect::Rect; + use crate::values::generics::NonNegative; use crate::values::specified::SVGPathData; use std::borrow::Borrow; impl StyleShapeSource { /// Convert StyleShapeSource to ShapeSource except URL and Image /// types. fn into_shape_source<ReferenceBox, ImageOrUrl>( &self, @@ -836,20 +836,27 @@ pub mod basic_shape { } } } impl<'a> From<&'a nsStyleCorners> for BorderRadius { fn from(other: &'a nsStyleCorners) -> Self { let get_corner = |index| { BorderCornerRadius::new( - NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index)) - .expect("<border-radius> should be a length, percentage, or calc value")), - NonNegative(LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1)) - .expect("<border-radius> should be a length, percentage, or calc value")), + NonNegative( + LengthOrPercentage::from_gecko_style_coord(&other.data_at(index)).expect( + "<border-radius> should be a length, percentage, or calc value", + ), + ), + NonNegative( + LengthOrPercentage::from_gecko_style_coord(&other.data_at(index + 1)) + .expect( + "<border-radius> should be a length, percentage, or calc value", + ), + ), ) }; GenericBorderRadius { top_left: get_corner(0), top_right: get_corner(2), bottom_right: get_corner(4), bottom_left: get_corner(6),
--- a/servo/components/style/gecko/data.rs +++ b/servo/components/style/gecko/data.rs @@ -1,28 +1,28 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Data needed to style a Gecko document. -use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; use crate::context::QuirksMode; use crate::dom::TElement; use crate::gecko_bindings::bindings::{self, RawServoStyleSet}; +use crate::gecko_bindings::structs::{RawGeckoPresContextBorrowed, ServoStyleSetSizes}; use crate::gecko_bindings::structs::{StyleSheet as DomStyleSheet, StyleSheetInfo}; -use crate::gecko_bindings::structs::{RawGeckoPresContextBorrowed, ServoStyleSetSizes}; use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI}; use crate::invalidation::media_queries::{MediaListKey, ToMediaListKey}; use crate::media_queries::{Device, MediaList}; use crate::properties::ComputedValues; use crate::selector_parser::SnapshotMap; use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; use crate::stylesheets::{CssRule, Origin, StylesheetContents, StylesheetInDocument}; use crate::stylist::Stylist; +use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; use malloc_size_of::MallocSizeOfOps; use servo_arc::Arc; use std::fmt; /// Little wrapper to a Gecko style sheet. #[derive(Eq, PartialEq)] pub struct GeckoStyleSheet(*const DomStyleSheet); @@ -145,18 +145,17 @@ impl PerDocumentStyleData { /// Create a dummy `PerDocumentStyleData`. pub fn new(pres_context: RawGeckoPresContextBorrowed) -> Self { let device = Device::new(pres_context); // FIXME(emilio, tlin): How is this supposed to work with XBL? This is // right now not always honored, see bug 1405543... // // Should we just force XBL Stylists to be NoQuirks? - let quirks_mode = - unsafe { (*device.pres_context().mDocument.mRawPtr).mCompatMode }; + let quirks_mode = unsafe { (*device.pres_context().mDocument.mRawPtr).mCompatMode }; PerDocumentStyleData(AtomicRefCell::new(PerDocumentStyleDataImpl { stylist: Stylist::new(device, quirks_mode.into()), })) } /// Get an immutable reference to this style data. pub fn borrow(&self) -> AtomicRef<PerDocumentStyleDataImpl> { @@ -187,22 +186,17 @@ impl PerDocumentStyleDataImpl { /// Get the default computed values for this document. pub fn default_computed_values(&self) -> &Arc<ComputedValues> { self.stylist.device().default_computed_values_arc() } /// Returns whether visited styles are enabled. #[inline] pub fn visited_styles_enabled(&self) -> bool { - let doc = self - .stylist - .device() - .pres_context() - .mDocument - .mRawPtr; + let doc = self.stylist.device().pres_context().mDocument.mRawPtr; unsafe { bindings::Gecko_VisitedStylesEnabled(doc) } } /// Measure heap usage. pub fn add_size_of(&self, ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSetSizes) { self.stylist.add_size_of(ops, sizes); } }
deleted file mode 100644 --- a/servo/components/style/gecko/global_style_data.rs +++ /dev/null @@ -1,117 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ - -//! Global style data - -use crate::context::StyleSystemOptions; -use crate::gecko_bindings::bindings; -use crate::parallel::STYLE_THREAD_STACK_SIZE_KB; -use crate::shared_lock::SharedRwLock; -use crate::thread_state; -use num_cpus; -use rayon; -use std::cmp; -use std::env; -use std::ffi::CString; - -/// Global style data -pub struct GlobalStyleData { - /// Shared RWLock for CSSOM objects - pub shared_lock: SharedRwLock, - - /// Global style system options determined by env vars. - pub options: StyleSystemOptions, -} - -/// Global thread pool -pub struct StyleThreadPool { - /// How many threads parallel styling can use. - pub num_threads: usize, - - /// The parallel styling thread pool. - pub style_thread_pool: Option<rayon::ThreadPool>, -} - -fn thread_name(index: usize) -> String { - format!("StyleThread#{}", index) -} - -fn thread_startup(index: usize) { - thread_state::initialize_layout_worker_thread(); - unsafe { - bindings::Gecko_SetJemallocThreadLocalArena(true); - } - let name = thread_name(index); - let name = CString::new(name).unwrap(); - unsafe { - // Gecko_RegisterProfilerThread copies the passed name here. - bindings::Gecko_RegisterProfilerThread(name.as_ptr()); - } -} - -fn thread_shutdown(_: usize) { - unsafe { - bindings::Gecko_UnregisterProfilerThread(); - bindings::Gecko_SetJemallocThreadLocalArena(false); - } -} - -lazy_static! { - /// Global thread pool - pub static ref STYLE_THREAD_POOL: StyleThreadPool = { - let stylo_threads = env::var("STYLO_THREADS") - .map(|s| s.parse::<usize>().expect("invalid STYLO_THREADS value")); - let mut num_threads = match stylo_threads { - Ok(num) => num, - // The default heuristic is num_virtual_cores * .75. This gives us - // three threads on a hyper-threaded dual core, and six threads on - // a hyper-threaded quad core. The performance benefit of additional - // threads seems to level off at around six, so we cap it there on - // many-core machines (see bug 1431285 comment 14). - _ => cmp::min(cmp::max(num_cpus::get() * 3 / 4, 1), 6), - }; - - // If num_threads is one, there's no point in creating a thread pool, so - // force it to zero. - // - // We allow developers to force a one-thread pool for testing via a - // special environmental variable. - if num_threads == 1 { - let force_pool = env::var("FORCE_STYLO_THREAD_POOL") - .ok().map_or(false, |s| s.parse::<usize>().expect("invalid FORCE_STYLO_THREAD_POOL value") == 1); - if !force_pool { - num_threads = 0; - } - } - - let pool = if num_threads < 1 { - None - } else { - let workers = rayon::ThreadPoolBuilder::new() - .num_threads(num_threads) - // Enable a breadth-first rayon traversal. This causes the work - // queue to be always FIFO, rather than FIFO for stealers and - // FILO for the owner (which is what rayon does by default). This - // ensures that we process all the elements at a given depth before - // proceeding to the next depth, which is important for style sharing. - .breadth_first() - .thread_name(thread_name) - .start_handler(thread_startup) - .exit_handler(thread_shutdown) - .stack_size(STYLE_THREAD_STACK_SIZE_KB * 1024) - .build(); - workers.ok() - }; - - StyleThreadPool { - num_threads: num_threads, - style_thread_pool: pool, - } - }; - /// Global style data - pub static ref GLOBAL_STYLE_DATA: GlobalStyleData = GlobalStyleData { - shared_lock: SharedRwLock::new(), - options: StyleSystemOptions::default(), - }; -}
--- a/servo/components/style/gecko/media_features.rs +++ b/servo/components/style/gecko/media_features.rs @@ -1,24 +1,24 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Gecko's media feature list and evaluator. -use app_units::Au; use crate::gecko_bindings::bindings; use crate::gecko_bindings::structs; use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements}; use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription}; use crate::media_queries::media_feature_expression::{AspectRatio, RangeOrOperator}; use crate::media_queries::{Device, MediaType}; use crate::values::computed::CSSPixelLength; use crate::values::computed::Resolution; use crate::Atom; +use app_units::Au; use euclid::Size2D; fn viewport_size(device: &Device) -> Size2D<Au> { let pc = device.pres_context(); if pc.mIsRootPaginatedDocument() != 0 { // We want the page size, including unprintable areas and margins. // FIXME(emilio, bug 1414600): Not quite! let area = &pc.mPageSize; @@ -315,18 +315,17 @@ fn eval_overflow_block(device: &Device, // If this ever changes, don't forget to change eval_overflow_inline too. let scrolling = device.media_type() != MediaType::print(); let query_value = match query_value { Some(v) => v, None => return true, }; match query_value { - OverflowBlock::None | - OverflowBlock::OptionalPaged => false, + OverflowBlock::None | OverflowBlock::OptionalPaged => false, OverflowBlock::Scroll => scrolling, OverflowBlock::Paged => !scrolling, } } #[derive(Clone, Copy, Debug, FromPrimitive, Parse, ToCss)] #[repr(u8)] enum OverflowInline {
--- a/servo/components/style/gecko/media_queries.rs +++ b/servo/components/style/gecko/media_queries.rs @@ -1,26 +1,26 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Gecko's media-query device and expression representation. -use app_units::Au; -use app_units::AU_PER_PX; use crate::custom_properties::CssEnvironment; use crate::gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor}; use crate::gecko_bindings::bindings; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::{nsPresContext, RawGeckoPresContextBorrowed}; use crate::media_queries::MediaType; use crate::properties::ComputedValues; use crate::string_cache::Atom; use crate::values::computed::font::FontSize; use crate::values::{CustomIdent, KeyframesName}; +use app_units::Au; +use app_units::AU_PER_PX; use cssparser::RGBA; use euclid::Size2D; use euclid::TypedScale; use servo_arc::Arc; use std::fmt; use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering}; use style_traits::viewport::ViewportConstraints; use style_traits::{CSSPixel, DevicePixel};
--- a/servo/components/style/gecko/mod.rs +++ b/servo/components/style/gecko/mod.rs @@ -5,17 +5,16 @@ //! Gecko-specific style-system bits. #[macro_use] mod non_ts_pseudo_class_list; pub mod arc_types; pub mod conversions; pub mod data; -pub mod global_style_data; pub mod media_features; pub mod media_queries; pub mod pseudo_element; pub mod restyle_damage; pub mod rules; pub mod selector_parser; pub mod snapshot; pub mod snapshot_helpers;
--- a/servo/components/style/gecko/selector_parser.rs +++ b/servo/components/style/gecko/selector_parser.rs @@ -225,43 +225,44 @@ impl NonTSPseudoClass { NonTSPseudoClass::MozWindowInactive => DocumentState::NS_DOCUMENT_STATE_WINDOW_INACTIVE, _ => DocumentState::empty(), } } /// Returns true if the given pseudoclass should trigger style sharing cache /// revalidation. pub fn needs_cache_revalidation(&self) -> bool { - self.state_flag().is_empty() && !matches!(*self, - // :-moz-any is handled by the revalidation visitor walking - // the things inside it; it does not need to cause - // revalidation on its own. - NonTSPseudoClass::MozAny(_) | - // :dir() depends on state only, but doesn't use state_flag - // because its semantics don't quite match. Nevertheless, it - // doesn't need cache revalidation, because we already compare - // states for elements and candidates. - NonTSPseudoClass::Dir(_) | - // :-moz-is-html only depends on the state of the document and - // the namespace of the element; the former is invariant - // across all the elements involved and the latter is already - // checked for by our caching precondtions. - NonTSPseudoClass::MozIsHTML | - // :-moz-placeholder is parsed but never matches. - NonTSPseudoClass::MozPlaceholder | - // :-moz-locale-dir and :-moz-window-inactive depend only on - // the state of the document, which is invariant across all - // the elements involved in a given style cache. - NonTSPseudoClass::MozLocaleDir(_) | - NonTSPseudoClass::MozWindowInactive | - // Similar for the document themes. - NonTSPseudoClass::MozLWTheme | - NonTSPseudoClass::MozLWThemeBrightText | - NonTSPseudoClass::MozLWThemeDarkText - ) + self.state_flag().is_empty() && + !matches!(*self, + // :-moz-any is handled by the revalidation visitor walking + // the things inside it; it does not need to cause + // revalidation on its own. + NonTSPseudoClass::MozAny(_) | + // :dir() depends on state only, but doesn't use state_flag + // because its semantics don't quite match. Nevertheless, it + // doesn't need cache revalidation, because we already compare + // states for elements and candidates. + NonTSPseudoClass::Dir(_) | + // :-moz-is-html only depends on the state of the document and + // the namespace of the element; the former is invariant + // across all the elements involved and the latter is already + // checked for by our caching precondtions. + NonTSPseudoClass::MozIsHTML | + // :-moz-placeholder is parsed but never matches. + NonTSPseudoClass::MozPlaceholder | + // :-moz-locale-dir and :-moz-window-inactive depend only on + // the state of the document, which is invariant across all + // the elements involved in a given style cache. + NonTSPseudoClass::MozLocaleDir(_) | + NonTSPseudoClass::MozWindowInactive | + // Similar for the document themes. + NonTSPseudoClass::MozLWTheme | + NonTSPseudoClass::MozLWThemeBrightText | + NonTSPseudoClass::MozLWThemeDarkText + ) } /// Returns true if the evaluation of the pseudo-class depends on the /// element's attributes. pub fn is_attr_based(&self) -> bool { matches!( *self, NonTSPseudoClass::MozTableBorderNonzero |
--- a/servo/components/style/gecko/values.rs +++ b/servo/components/style/gecko/values.rs @@ -1,17 +1,16 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #![allow(unsafe_code)] //! Different kind of helpers to interact with Gecko values. -use app_units::Au; use crate::counter_style::{Symbol, Symbols}; use crate::gecko_bindings::structs::{self, nsStyleCoord, CounterStylePtr}; use crate::gecko_bindings::structs::{StyleGridTrackBreadth, StyleShapeRadius}; use crate::gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; use crate::media_queries::Device; use crate::values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; use crate::values::computed::FlexBasis as ComputedFlexBasis; use crate::values::computed::{Angle, ExtremumLength, Length, LengthOrPercentage}; @@ -22,16 +21,17 @@ use crate::values::generics::basic_shape use crate::values::generics::box_::Perspective; use crate::values::generics::flex::FlexBasis; use crate::values::generics::gecko::ScrollSnapPoint; use crate::values::generics::grid::{TrackBreadth, TrackKeyword}; use crate::values::generics::length::{MaxLength, MozLength}; use crate::values::generics::{CounterStyleOrNone, NonNegative}; use crate::values::{Auto, Either, None_, Normal}; use crate::Atom; +use app_units::Au; use cssparser::RGBA; use nsstring::{nsACString, nsCStr}; use std::cmp::max; /// A trait that defines an interface to convert from and to `nsStyleCoord`s. /// /// TODO(emilio): Almost everything that is in this file should be somehow /// switched to cbindgen. @@ -281,19 +281,17 @@ impl GeckoStyleCoordConvertible for Comp if v == StyleShapeRadius::ClosestSide as u32 { Some(ShapeRadius::ClosestSide) } else if v == StyleShapeRadius::FarthestSide as u32 { Some(ShapeRadius::FarthestSide) } else { None } }, - _ => { - GeckoStyleCoordConvertible::from_gecko_style_coord(coord).map(ShapeRadius::Length) - }, + _ => GeckoStyleCoordConvertible::from_gecko_style_coord(coord).map(ShapeRadius::Length), } } } impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> { fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) { if let Some(ref me) = *self { me.to_gecko_style_coord(coord);
--- a/servo/components/style/gecko/wrapper.rs +++ b/servo/components/style/gecko/wrapper.rs @@ -9,27 +9,24 @@ //! //! This really follows the Servo pattern in //! `components/script/layout_wrapper.rs`. //! //! This theoretically should live in its own crate, but now it lives in the //! style system it's kind of pointless in the Stylo case, and only Servo forces //! the separation between the style system implementation and everything else. -use app_units::Au; -use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use crate::applicable_declarations::ApplicableDeclarationBlock; use crate::author_styles::AuthorStyles; use crate::context::{PostAnimationTasks, QuirksMode, SharedStyleContext, UpdateAnimationsTasks}; use crate::data::ElementData; use crate::dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot}; use crate::element_state::{DocumentState, ElementState}; use crate::font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult}; use crate::gecko::data::GeckoStyleSheet; -use crate::gecko::global_style_data::GLOBAL_STYLE_DATA; use crate::gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl}; use crate::gecko::snapshot_helpers; use crate::gecko_bindings::bindings; use crate::gecko_bindings::bindings::Gecko_ElementHasAnimations; use crate::gecko_bindings::bindings::Gecko_ElementHasCSSAnimations; use crate::gecko_bindings::bindings::Gecko_ElementHasCSSTransitions; use crate::gecko_bindings::bindings::Gecko_GetActiveLinkAttrDeclarationBlock; use crate::gecko_bindings::bindings::Gecko_GetAnimationEffectCount; @@ -42,41 +39,44 @@ use crate::gecko_bindings::bindings::Gec use crate::gecko_bindings::bindings::Gecko_IsSignificantChild; use crate::gecko_bindings::bindings::Gecko_MatchLang; use crate::gecko_bindings::bindings::Gecko_UnsetDirtyStyleAttr; use crate::gecko_bindings::bindings::Gecko_UpdateAnimations; use crate::gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme}; use crate::gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; use crate::gecko_bindings::structs; use crate::gecko_bindings::structs::nsChangeHint; +use crate::gecko_bindings::structs::nsRestyleHint; use crate::gecko_bindings::structs::Document_DocumentTheme as DocumentTheme; -use crate::gecko_bindings::structs::nsRestyleHint; use crate::gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; use crate::gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT; use crate::gecko_bindings::structs::ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO; use crate::gecko_bindings::structs::ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO; use crate::gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT; use crate::gecko_bindings::structs::NODE_DESCENDANTS_NEED_FRAMES; use crate::gecko_bindings::structs::NODE_NEEDS_FRAME; use crate::gecko_bindings::structs::{nsAtom, nsIContent, nsINode_BooleanFlag}; use crate::gecko_bindings::structs::{RawGeckoElement, RawGeckoNode, RawGeckoXBLBinding}; use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI}; +use crate::global_style_data::GLOBAL_STYLE_DATA; use crate::hash::FxHashMap; use crate::logical_geometry::WritingMode; use crate::media_queries::Device; use crate::properties::animated_properties::{AnimationValue, AnimationValueMap}; use crate::properties::style_structs::Font; use crate::properties::{ComputedValues, LonghandId}; use crate::properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; use crate::rule_tree::CascadeLevel as ServoCascadeLevel; use crate::selector_parser::{AttrValue, HorizontalDirection, Lang}; use crate::shared_lock::Locked; use crate::string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; use crate::stylist::CascadeData; use crate::CaseSensitivityExt; +use app_units::Au; +use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator}; use selectors::attr::{CaseSensitivity, NamespaceConstraint}; use selectors::matching::VisitedHandlingMode; use selectors::matching::{ElementSelectorFlags, MatchingContext}; use selectors::sink::Push; use selectors::{Element, OpaqueElement}; use servo_arc::{Arc, ArcBorrow, RawOffsetArc}; use std::cell::RefCell; @@ -926,23 +926,24 @@ impl<'le> GeckoElement<'le> { return ***existing != after_value; } let from = AnimationValue::from_computed_values(longhand_id, before_change_style); let to = AnimationValue::from_computed_values(longhand_id, after_change_style); debug_assert_eq!(to.is_some(), from.is_some()); - combined_duration > 0.0f32 && from != to && from - .unwrap() - .animate( - to.as_ref().unwrap(), - Procedure::Interpolate { progress: 0.5 }, - ) - .is_ok() + combined_duration > 0.0f32 && + from != to && + from.unwrap() + .animate( + to.as_ref().unwrap(), + Procedure::Interpolate { progress: 0.5 }, + ) + .is_ok() } } /// Converts flags from the layout used by rust-selectors to the layout used /// by Gecko. We could align these and then do this without conditionals, but /// it's probably not worth the trouble. fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 { use crate::gecko_bindings::structs::*; @@ -1236,20 +1237,18 @@ impl<'le> TElement for GeckoElement<'le> } #[inline] fn as_node(&self) -> Self::ConcreteNode { unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) } } fn owner_doc_matches_for_testing(&self, device: &Device) -> bool { - self.as_node().owner_doc().0 as *const structs::Document == device - .pres_context() - .mDocument - .mRawPtr + self.as_node().owner_doc().0 as *const structs::Document == + device.pres_context().mDocument.mRawPtr } fn style_attribute(&self) -> Option<ArcBorrow<Locked<PropertyDeclarationBlock>>> { if !self.may_have_style_attribute() { return None; } let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) }; @@ -1856,19 +1855,18 @@ impl<'le> TElement for GeckoElement<'le> )); } let active = self .state() .intersects(NonTSPseudoClass::Active.state_flag()); if active { let declarations = unsafe { Gecko_GetActiveLinkAttrDeclarationBlock(self.0) }; - let declarations: Option< - &RawOffsetArc<Locked<PropertyDeclarationBlock>>, - > = declarations.and_then(|s| s.as_arc_opt()); + let declarations: Option<&RawOffsetArc<Locked<PropertyDeclarationBlock>>> = + declarations.and_then(|s| s.as_arc_opt()); if let Some(decl) = declarations { hints.push(ApplicableDeclarationBlock::from_declarations( decl.clone_arc(), ServoCascadeLevel::PresHints, )); } } } @@ -2073,21 +2071,20 @@ impl<'le> ::selectors::Element for Gecko { return false; } if !self.as_node().is_in_document() { return false; } - debug_assert!( - self.as_node() - .parent_node() - .map_or(false, |p| p.is_document()) - ); + debug_assert!(self + .as_node() + .parent_node() + .map_or(false, |p| p.is_document())); unsafe { bindings::Gecko_IsRootElement(self.0) } } fn is_empty(&self) -> bool { !self .as_node() .dom_children() .any(|child| unsafe { Gecko_IsSignificantChild(child.0, true) })
--- a/servo/components/style/gecko_bindings/mod.rs +++ b/servo/components/style/gecko_bindings/mod.rs @@ -1,20 +1,15 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Gecko's C++ bindings, along with some rust helpers to ease its use. -#[allow( - dead_code, - improper_ctypes, - non_camel_case_types, - missing_docs -)] +#[allow(dead_code, improper_ctypes, non_camel_case_types, missing_docs)] pub mod bindings { include!(concat!(env!("OUT_DIR"), "/gecko/bindings.rs")); } // FIXME: We allow `improper_ctypes` (for now), because the lint doesn't allow // foreign structs to have `PhantomData`. We should remove this once the lint // ignores this case.
--- a/servo/components/style/gecko_bindings/sugar/ns_css_shadow_item.rs +++ b/servo/components/style/gecko_bindings/sugar/ns_css_shadow_item.rs @@ -1,17 +1,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Rust helpers for Gecko's `nsCSSShadowItem`. -use app_units::Au; use crate::gecko_bindings::structs::nsCSSShadowItem; use crate::values::computed::effects::{BoxShadow, SimpleShadow}; +use app_units::Au; impl nsCSSShadowItem { /// Sets this item from the given box shadow. #[inline] pub fn set_from_box_shadow(&mut self, shadow: BoxShadow) { self.set_from_simple_shadow(shadow.base); self.mSpread = shadow.spread.to_i32_au(); self.mInset = shadow.inset;
--- a/servo/components/style/gecko_bindings/sugar/origin_flags.rs +++ b/servo/components/style/gecko_bindings/sugar/origin_flags.rs @@ -5,17 +5,20 @@ //! Helper to iterate over `OriginFlags` bits. use crate::gecko_bindings::structs::OriginFlags; use crate::stylesheets::OriginSet; /// Checks that the values for OriginFlags are the ones we expect. pub fn assert_flags_match() { use crate::stylesheets::origin::*; - debug_assert_eq!(OriginFlags::UserAgent.0, OriginSet::ORIGIN_USER_AGENT.bits()); + debug_assert_eq!( + OriginFlags::UserAgent.0, + OriginSet::ORIGIN_USER_AGENT.bits() + ); debug_assert_eq!(OriginFlags::Author.0, OriginSet::ORIGIN_AUTHOR.bits()); debug_assert_eq!(OriginFlags::User.0, OriginSet::ORIGIN_USER.bits()); } impl From<OriginFlags> for OriginSet { fn from(flags: OriginFlags) -> Self { Self::from_bits_truncate(flags.0) }
new file mode 100644 --- /dev/null +++ b/servo/components/style/global_style_data.rs @@ -0,0 +1,131 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Global style data + +use crate::context::StyleSystemOptions; +#[cfg(feature = "gecko")] +use crate::gecko_bindings::bindings; +use crate::parallel::STYLE_THREAD_STACK_SIZE_KB; +use crate::shared_lock::SharedRwLock; +use crate::thread_state; +use rayon; +use std::env; + +/// Global style data +pub struct GlobalStyleData { + /// Shared RWLock for CSSOM objects + pub shared_lock: SharedRwLock, + + /// Global style system options determined by env vars. + pub options: StyleSystemOptions, +} + +/// Global thread pool +pub struct StyleThreadPool { + /// How many threads parallel styling can use. + pub num_threads: usize, + + /// The parallel styling thread pool. + pub style_thread_pool: Option<rayon::ThreadPool>, +} + +fn thread_name(index: usize) -> String { + format!("StyleThread#{}", index) +} + +fn thread_startup(_index: usize) { + thread_state::initialize_layout_worker_thread(); + #[cfg(feature = "gecko")] + unsafe { + use std::ffi::CString; + + bindings::Gecko_SetJemallocThreadLocalArena(true); + let name = thread_name(_index); + let name = CString::new(name).unwrap(); + // Gecko_RegisterProfilerThread copies the passed name here. + bindings::Gecko_RegisterProfilerThread(name.as_ptr()); + } +} + +fn thread_shutdown(_: usize) { + #[cfg(feature = "gecko")] + unsafe { + bindings::Gecko_UnregisterProfilerThread(); + bindings::Gecko_SetJemallocThreadLocalArena(false); + } +} + +lazy_static! { + /// Global thread pool + pub static ref STYLE_THREAD_POOL: StyleThreadPool = { + let stylo_threads = env::var("STYLO_THREADS") + .map(|s| s.parse::<usize>().expect("invalid STYLO_THREADS value")); + let mut num_threads = match stylo_threads { + Ok(num) => num, + #[cfg(feature = "servo")] + _ => { + // We always set this pref on startup, before layout or script + // have had a chance of accessing (and thus creating) the + // thread-pool. + use servo_config::prefs::PREFS; + PREFS.get("layout.threads").as_u64().unwrap() as usize + } + #[cfg(feature = "gecko")] + _ => { + // The default heuristic is num_virtual_cores * .75. This gives + // us three threads on a hyper-threaded dual core, and six + // threads on a hyper-threaded quad core. The performance + // benefit of additional threads seems to level off at around + // six, so we cap it there on many-core machines + // (see bug 1431285 comment 14). + use num_cpus; + use std::cmp; + cmp::min(cmp::max(num_cpus::get() * 3 / 4, 1), 6) + } + }; + + // If num_threads is one, there's no point in creating a thread pool, so + // force it to zero. + // + // We allow developers to force a one-thread pool for testing via a + // special environmental variable. + if num_threads == 1 { + let force_pool = env::var("FORCE_STYLO_THREAD_POOL") + .ok().map_or(false, |s| s.parse::<usize>().expect("invalid FORCE_STYLO_THREAD_POOL value") == 1); + if !force_pool { + num_threads = 0; + } + } + + let pool = if num_threads < 1 { + None + } else { + let workers = rayon::ThreadPoolBuilder::new() + .num_threads(num_threads) + // Enable a breadth-first rayon traversal. This causes the work + // queue to be always FIFO, rather than FIFO for stealers and + // FILO for the owner (which is what rayon does by default). This + // ensures that we process all the elements at a given depth before + // proceeding to the next depth, which is important for style sharing. + .breadth_first() + .thread_name(thread_name) + .start_handler(thread_startup) + .exit_handler(thread_shutdown) + .stack_size(STYLE_THREAD_STACK_SIZE_KB * 1024) + .build(); + workers.ok() + }; + + StyleThreadPool { + num_threads: num_threads, + style_thread_pool: pool, + } + }; + /// Global style data + pub static ref GLOBAL_STYLE_DATA: GlobalStyleData = GlobalStyleData { + shared_lock: SharedRwLock::new(), + options: StyleSystemOptions::default(), + }; +}
--- a/servo/components/style/invalidation/element/element_wrapper.rs +++ b/servo/components/style/invalidation/element/element_wrapper.rs @@ -203,20 +203,20 @@ where }, // For :link and :visited, we don't actually want to test the // element state directly. // // Instead, we use the `visited_handling` to determine if they // match. NonTSPseudoClass::Link => { - return self.is_link() && context.visited_handling().matches_unvisited() + return self.is_link() && context.visited_handling().matches_unvisited(); }, NonTSPseudoClass::Visited => { - return self.is_link() && context.visited_handling().matches_visited() + return self.is_link() && context.visited_handling().matches_visited(); }, #[cfg(feature = "gecko")] NonTSPseudoClass::MozTableBorderNonzero => { if let Some(snapshot) = self.snapshot() { if snapshot.has_other_pseudo_class_state() { return snapshot.mIsTableBorderNonzero(); }
--- a/servo/components/style/invalidation/element/restyle_hints.rs +++ b/servo/components/style/invalidation/element/restyle_hints.rs @@ -200,23 +200,27 @@ impl From<nsRestyleHint> for RestyleHint "Handle later siblings manually if necessary plz." ); if (raw.0 & (nsRestyleHint::eRestyle_Self.0 | nsRestyleHint::eRestyle_Subtree.0)) != 0 { raw.0 &= !nsRestyleHint::eRestyle_Self.0; hint.insert(RestyleHint::RESTYLE_SELF); } - if (raw.0 & (nsRestyleHint::eRestyle_Subtree.0 | nsRestyleHint::eRestyle_SomeDescendants.0)) != 0 { + if (raw.0 & (nsRestyleHint::eRestyle_Subtree.0 | nsRestyleHint::eRestyle_SomeDescendants.0)) != + 0 + { raw.0 &= !nsRestyleHint::eRestyle_Subtree.0; raw.0 &= !nsRestyleHint::eRestyle_SomeDescendants.0; hint.insert(RestyleHint::RESTYLE_DESCENDANTS); } - if (raw.0 & (nsRestyleHint::eRestyle_ForceDescendants.0 | nsRestyleHint::eRestyle_Force.0)) != 0 { + if (raw.0 & (nsRestyleHint::eRestyle_ForceDescendants.0 | nsRestyleHint::eRestyle_Force.0)) != + 0 + { raw.0 &= !nsRestyleHint::eRestyle_Force.0; hint.insert(RestyleHint::RECASCADE_SELF); } if (raw.0 & nsRestyleHint::eRestyle_ForceDescendants.0) != 0 { raw.0 &= !nsRestyleHint::eRestyle_ForceDescendants.0; hint.insert(RestyleHint::RECASCADE_DESCENDANTS); }
--- a/servo/components/style/lib.rs +++ b/servo/components/style/lib.rs @@ -128,16 +128,17 @@ pub mod element_state; #[cfg(feature = "servo")] mod encoding_support; pub mod error_reporting; pub mod font_face; pub mod font_metrics; #[cfg(feature = "gecko")] #[allow(unsafe_code)] pub mod gecko_bindings; +pub mod global_style_data; pub mod hash; pub mod invalidation; #[allow(missing_docs)] // TODO. pub mod logical_geometry; pub mod matching; #[macro_use] pub mod media_queries; pub mod parallel;
--- a/servo/components/style/logical_geometry.rs +++ b/servo/components/style/logical_geometry.rs @@ -1216,21 +1216,22 @@ impl<T: Copy + Add<T, Output = T> + Sub< LogicalRect { start: self.start + offset, ..*self } } pub fn translate(&self, offset: &LogicalPoint<T>) -> LogicalRect<T> { LogicalRect { - start: self.start + LogicalSize { - inline: offset.i, - block: offset.b, - debug_writing_mode: offset.debug_writing_mode, - }, + start: self.start + + LogicalSize { + inline: offset.i, + block: offset.b, + debug_writing_mode: offset.debug_writing_mode, + }, size: self.size, debug_writing_mode: self.debug_writing_mode, } } } impl<T: Copy + Ord + Add<T, Output = T> + Sub<T, Output = T>> LogicalRect<T> { #[inline]
--- a/servo/components/style/matching.rs +++ b/servo/components/style/matching.rs @@ -464,21 +464,19 @@ trait PrivateMatchMethods: TElement { &self, shared_context: &SharedStyleContext, damage: &mut RestyleDamage, old_values: &ComputedValues, new_values: &ComputedValues, pseudo: Option<&PseudoElement>, ) -> ChildCascadeRequirement { debug!("accumulate_damage_for: {:?}", self); - debug_assert!( - !shared_context - .traversal_flags - .contains(TraversalFlags::Forgetful) - ); + debug_assert!(!shared_context + .traversal_flags + .contains(TraversalFlags::Forgetful)); let difference = self.compute_style_difference(old_values, new_values, pseudo); *damage |= difference.damage; debug!(" > style difference: {:?}", difference); // We need to cascade the children in order to ensure the correct
--- a/servo/components/style/media_queries/media_feature.rs +++ b/servo/components/style/media_queries/media_feature.rs @@ -25,19 +25,20 @@ type MediaFeatureEvaluator<T> = fn( /// Serializes a given discriminant. /// /// FIXME(emilio): we could prevent this allocation if the ToCss code would /// generate a method for keywords to get the static string or something. pub type KeywordSerializer = fn(KeywordDiscriminant) -> String; /// Parses a given identifier. -pub type KeywordParser = - for<'a, 'i, 't> fn(context: &'a ParserContext, input: &'a mut Parser<'i, 't>) - -> Result<KeywordDiscriminant, ParseError<'i>>; +pub type KeywordParser = for<'a, 'i, 't> fn( + context: &'a ParserContext, + input: &'a mut Parser<'i, 't>, +) -> Result<KeywordDiscriminant, ParseError<'i>>; /// An evaluator for a given media feature. /// /// This determines the kind of values that get parsed, too. #[allow(missing_docs)] pub enum Evaluator { Length(MediaFeatureEvaluator<CSSPixelLength>), Integer(MediaFeatureEvaluator<u32>),
--- a/servo/components/style/media_queries/media_feature_expression.rs +++ b/servo/components/style/media_queries/media_feature_expression.rs @@ -129,20 +129,21 @@ impl RangeOrOperator { let range_or_op = match range_or_op { Some(r) => r, None => return cmp == Ordering::Equal, }; match range_or_op { RangeOrOperator::Range(range) => { - cmp == Ordering::Equal || match range { - Range::Min => cmp == Ordering::Greater, - Range::Max => cmp == Ordering::Less, - } + cmp == Ordering::Equal || + match range { + Range::Min => cmp == Ordering::Greater, + Range::Max => cmp == Ordering::Less, + } }, RangeOrOperator::Operator(op) => match op { Operator::Equal => cmp == Ordering::Equal, Operator::GreaterThan => cmp == Ordering::Greater, Operator::GreaterThanEqual => cmp == Ordering::Equal || cmp == Ordering::Greater, Operator::LessThan => cmp == Ordering::Less, Operator::LessThanEqual => cmp == Ordering::Equal || cmp == Ordering::Less, }, @@ -339,17 +340,17 @@ impl MediaFeatureExpression { Ok((i, f, r)) => { feature_index = i; feature = f; range = r; }, Err(()) => { return Err(location.new_custom_error( StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), - )) + )); }, } if !(feature.requirements & !requirements).is_empty() { return Err(location.new_custom_error( StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), )); }
--- a/servo/components/style/media_queries/media_list.rs +++ b/servo/components/style/media_queries/media_list.rs @@ -69,31 +69,32 @@ impl MediaList { media_queries: vec![], } } /// Evaluate a whole `MediaList` against `Device`. pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> bool { // Check if it is an empty media query list or any queries match. // https://drafts.csswg.org/mediaqueries-4/#mq-list - self.media_queries.is_empty() || self.media_queries.iter().any(|mq| { - let media_match = mq.media_type.matches(device.media_type()); + self.media_queries.is_empty() || + self.media_queries.iter().any(|mq| { + let media_match = mq.media_type.matches(device.media_type()); - // Check if the media condition match. - let query_match = media_match && mq - .condition - .as_ref() - .map_or(true, |c| c.matches(device, quirks_mode)); + // Check if the media condition match. + let query_match = media_match && + mq.condition + .as_ref() + .map_or(true, |c| c.matches(device, quirks_mode)); - // Apply the logical NOT qualifier to the result - match mq.qualifier { - Some(Qualifier::Not) => !query_match, - _ => query_match, - } - }) + // Apply the logical NOT qualifier to the result + match mq.qualifier { + Some(Qualifier::Not) => !query_match, + _ => query_match, + } + }) } /// Whether this `MediaList` contains no media queries. pub fn is_empty(&self) -> bool { self.media_queries.is_empty() } /// Append a new media query item to the media list.
--- a/servo/components/style/parallel.rs +++ b/servo/components/style/parallel.rs @@ -17,21 +17,21 @@ //! share them with other threads. In the parallel traversal, we explicitly //! invoke |unsafe { SendNode::new(n) }| to put nodes in containers that may //! be sent to other threads. This occurs in only a handful of places and is //! easy to grep for. At the time of this writing, there is no other unsafe //! code in the parallel traversal. #![deny(missing_docs)] -use arrayvec::ArrayVec; use crate::context::{StyleContext, ThreadLocalStyleContext}; use crate::dom::{OpaqueNode, SendNode, TElement}; use crate::scoped_tls::ScopedTLS; use crate::traversal::{DomTraversal, PerLevelTraversalData}; +use arrayvec::ArrayVec; use itertools::Itertools; use rayon; use smallvec::SmallVec; /// The minimum stack size for a thread in the styling pool, in kilobytes. pub const STYLE_THREAD_STACK_SIZE_KB: usize = 256; /// The stack margin. If we get this deep in the stack, we will skip recursive
--- a/servo/components/style/rule_collector.rs +++ b/servo/components/style/rule_collector.rs @@ -255,18 +255,17 @@ where Some(s) => s, None => return, }; self.matches_document_author_rules = false; let cascade_data = containing_shadow.style_data(); let host = containing_shadow.host(); - if let Some(map) = cascade_data.and_then(|data| data.normal_rules(self.pseudo_element)) - { + if let Some(map) = cascade_data.and_then(|data| data.normal_rules(self.pseudo_element)) { self.collect_rules_in_shadow_tree(host, map, CascadeLevel::SameTreeAuthorNormal); } } /// Collects the rules for the :host pseudo-class. fn collect_host_rules(&mut self) { let shadow = match self.rule_hash_target.shadow_root() { Some(s) => s,
--- a/servo/components/style/servo/media_queries.rs +++ b/servo/components/style/servo/media_queries.rs @@ -1,24 +1,24 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Servo's media-query device and expression representation. -use app_units::Au; use crate::custom_properties::CssEnvironment; use crate::media_queries::media_feature::{AllowsRanges, ParsingRequirements}; use crate::media_queries::media_feature::{Evaluator, MediaFeatureDescription}; use crate::media_queries::media_feature_expression::RangeOrOperator; use crate::media_queries::MediaType; use crate::properties::ComputedValues; use crate::values::computed::font::FontSize; use crate::values::computed::CSSPixelLength; use crate::values::KeyframesName; +use app_units::Au; use cssparser::RGBA; use euclid::{Size2D, TypedScale, TypedSize2D}; use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; use style_traits::viewport::ViewportConstraints; use style_traits::{CSSPixel, DevicePixel}; /// A device is a structure that represents the current media a given document /// is displayed in.
--- a/servo/components/style/servo/selector_parser.rs +++ b/servo/components/style/servo/selector_parser.rs @@ -452,17 +452,17 @@ impl<'a, 'i> ::selectors::Parser<'i> for } fn parse_non_ts_functional_pseudo_class<'t>( &self, name: CowRcStr<'i>, parser: &mut CssParser<'i, 't>, ) -> Result<NonTSPseudoClass, ParseError<'i>> { use self::NonTSPseudoClass::*; - let pseudo_class = match_ignore_ascii_case!{ &name, + let pseudo_class = match_ignore_ascii_case! { &name, "lang" => { Lang(parser.expect_ident_or_string()?.as_ref().into()) } "-servo-case-sensitive-type-attr" => { if !self.in_user_agent_stylesheet() { return Err(parser.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))); } ServoCaseSensitiveTypeAttr(Atom::from(parser.expect_ident()?.as_ref()))
--- a/servo/components/style/shared_lock.rs +++ b/servo/components/style/shared_lock.rs @@ -1,18 +1,18 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Different objects protected by the same lock +use crate::str::{CssString, CssStringWriter}; +use crate::stylesheets::Origin; #[cfg(feature = "gecko")] use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; -use crate::str::{CssString, CssStringWriter}; -use crate::stylesheets::Origin; #[cfg(feature = "servo")] use parking_lot::RwLock; use servo_arc::Arc; use std::cell::UnsafeCell; use std::fmt; #[cfg(feature = "servo")] use std::mem; #[cfg(feature = "gecko")]
--- a/servo/components/style/sharing/mod.rs +++ b/servo/components/style/sharing/mod.rs @@ -59,27 +59,27 @@ //! the up-front checks but would have different matching results for the //! selector in question. In this case, "descendants" includes pseudo-elements, //! so there is a single selector map of revalidation selectors that includes //! both selectors targeting elements and selectors targeting pseudo-element //! originating elements. We ensure that the pseudo-element parts of all these //! selectors are effectively stripped off, so that matching them all against //! elements makes sense. -use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use crate::applicable_declarations::ApplicableDeclarationBlock; use crate::bloom::StyleBloom; use crate::context::{SelectorFlagsMap, SharedStyleContext, StyleContext}; use crate::dom::{SendElement, TElement}; use crate::matching::MatchMethods; use crate::properties::ComputedValues; use crate::rule_tree::StrongRuleNode; use crate::style_resolver::{PrimaryStyle, ResolvedElementStyles}; use crate::stylist::Stylist; use crate::Atom; +use atomic_refcell::{AtomicRefCell, AtomicRefMut}; use owning_ref::OwningHandle; use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode}; use selectors::NthIndexCache; use servo_arc::Arc; use smallbitvec::SmallBitVec; use smallvec::SmallVec; use std::marker::PhantomData; use std::mem;
--- a/servo/components/style/style_adjuster.rs +++ b/servo/components/style/style_adjuster.rs @@ -1,23 +1,23 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! A struct to encapsulate all the style fixups and flags propagations //! a computed style needs in order for it to adhere to the CSS spec. -use app_units::Au; use crate::dom::TElement; use crate::properties::computed_value_flags::ComputedValueFlags; use crate::properties::longhands::display::computed_value::T as Display; use crate::properties::longhands::float::computed_value::T as Float; use crate::properties::longhands::overflow_x::computed_value::T as Overflow; use crate::properties::longhands::position::computed_value::T as Position; use crate::properties::{self, ComputedValues, StyleBuilder}; +use app_units::Au; /// A struct that implements all the adjustment methods. /// /// NOTE(emilio): If new adjustments are introduced that depend on reset /// properties of the parent, you may need tweaking the /// `ChildCascadeRequirement` code in `matching.rs`. /// /// NOTE(emilio): Also, if new adjustments are introduced that break the @@ -185,22 +185,20 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { blockify = $if_what; } }; } let is_root = self.style.pseudo.is_none() && element.map_or(false, |e| e.is_root()); blockify_if!(is_root); if !self.skip_item_display_fixup(element) { - blockify_if!( - layout_parent_style - .get_box() - .clone_display() - .is_item_container() - ); + blockify_if!(layout_parent_style + .get_box() + .clone_display() + .is_item_container()); } let is_item_or_root = blockify; blockify_if!(self.style.floated()); blockify_if!(self.style.out_of_flow_positioned()); if !blockify { @@ -215,21 +213,22 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { .set_adjusted_display(blockified_display, is_item_or_root); } } /// Compute a few common flags for both text and element's style. pub fn set_bits(&mut self) { let display = self.style.get_box().clone_display(); - if !display.is_contents() && !self - .style - .get_text() - .clone_text_decoration_line() - .is_empty() + if !display.is_contents() && + !self + .style + .get_text() + .clone_text_decoration_line() + .is_empty() { self.style .flags .insert(ComputedValueFlags::HAS_TEXT_DECORATION_LINES); } if self.style.is_pseudo_element() { self.style @@ -294,20 +293,20 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { /// additionally it applies it if it is in any ruby box. /// /// This is necessary because its parent may not itself have the flag set /// (e.g. ruby or ruby containers), thus we may not inherit the flag from /// them. #[cfg(feature = "gecko")] fn adjust_for_text_in_ruby(&mut self) { let parent_display = self.style.get_parent_box().clone_display(); - if parent_display.is_ruby_type() || self - .style - .get_parent_flags() - .contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK) + if parent_display.is_ruby_type() || + self.style + .get_parent_flags() + .contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK) { self.style .flags .insert(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK); } } /// <https://drafts.csswg.org/css-writing-modes-3/#block-flow:>
--- a/servo/components/style/stylesheets/font_feature_values_rule.rs +++ b/servo/components/style/stylesheets/font_feature_values_rule.rs @@ -65,21 +65,17 @@ impl Parse for SingleValue { fn parse<'i, 't>( _context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<SingleValue, ParseError<'i>> { let location = input.current_source_location(); match *input.next()? { Token::Number { int_value: Some(v), .. - } - if v >= 0 => - { - Ok(SingleValue(v as u32)) - }, + } if v >= 0 => Ok(SingleValue(v as u32)), ref t => Err(location.new_unexpected_token_error(t.clone())), } } } #[cfg(feature = "gecko")] impl ToGeckoFontFeatureValues for SingleValue { fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) { @@ -98,32 +94,24 @@ impl Parse for PairValues { fn parse<'i, 't>( _context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<PairValues, ParseError<'i>> { let location = input.current_source_location(); let first = match *input.next()? { Token::Number { int_value: Some(a), .. - } - if a >= 0 => - { - a as u32 - }, + } if a >= 0 => a as u32, ref t => return Err(location.new_unexpected_token_error(t.clone())), }; let location = input.current_source_location(); match input.next() { Ok(&Token::Number { int_value: Some(b), .. - }) - if b >= 0 => - { - Ok(PairValues(first, Some(b as u32))) - }, + }) if b >= 0 => Ok(PairValues(first, Some(b as u32))), // It can't be anything other than number. Ok(t) => Err(location.new_unexpected_token_error(t.clone())), // It can be just one value. Err(_) => Ok(PairValues(first, None)), } } } @@ -152,21 +140,19 @@ impl Parse for VectorValues { input: &mut Parser<'i, 't>, ) -> Result<VectorValues, ParseError<'i>> { let mut vec = vec![]; loop { let location = input.current_source_location(); match input.next() { Ok(&Token::Number { int_value: Some(a), .. - }) - if a >= 0 => - { + }) if a >= 0 => { vec.push(a as u32); - } + }, // It can't be anything other than number. Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(_) => break, } } if vec.len() == 0 { return Err(input.new_error(BasicParseErrorKind::EndOfInput));
--- a/servo/components/style/stylesheets/keyframes_rule.rs +++ b/servo/components/style/stylesheets/keyframes_rule.rs @@ -136,21 +136,17 @@ impl KeyframePercentage { Ok(KeyframePercentage::new(0.)) }, Token::Ident(ref identifier) if identifier.as_ref().eq_ignore_ascii_case("to") => { Ok(KeyframePercentage::new(1.)) }, Token::Percentage { unit_value: percentage, .. - } - if percentage >= 0. && percentage <= 1. => - { - Ok(KeyframePercentage::new(percentage)) - }, + } if percentage >= 0. && percentage <= 1. => Ok(KeyframePercentage::new(percentage)), _ => Err(input.new_unexpected_token_error(token)), } } } /// A keyframes selector is a list of percentages or from/to symbols, which are /// converted at parse time to percentages. #[css(comma)] @@ -595,17 +591,17 @@ impl<'a, 'b, 'i> DeclarationParser<'i> f fn parse_value<'t>( &mut self, name: CowRcStr<'i>, input: &mut Parser<'i, 't>, ) -> Result<(), ParseError<'i>> { let id = match PropertyId::parse(&name, self.context) { Ok(id) => id, Err(()) => { - return Err(input.new_custom_error(StyleParseErrorKind::UnknownProperty(name))) + return Err(input.new_custom_error(StyleParseErrorKind::UnknownProperty(name))); }, }; // TODO(emilio): Shouldn't this use parse_entirely? PropertyDeclaration::parse_into(self.declarations, id, self.context, input)?; // In case there is still unparsed text in the declaration, we should // roll back.
--- a/servo/components/style/stylesheets/rule_parser.rs +++ b/servo/components/style/stylesheets/rule_parser.rs @@ -102,19 +102,20 @@ impl<'b> TopLevelRuleParser<'b> { if new_state > next_rule_state { self.dom_error = Some(RulesMutateError::HierarchyRequest); return false; } // If there's anything that isn't a namespace rule (or import rule, but // we checked that already at the beginning), reject with a // StateError. - if new_state == State::Namespaces && ctx.rule_list[ctx.index..] - .iter() - .any(|r| !matches!(*r, CssRule::Namespace(..))) + if new_state == State::Namespaces && + ctx.rule_list[ctx.index..] + .iter() + .any(|r| !matches!(*r, CssRule::Namespace(..))) { self.dom_error = Some(RulesMutateError::InvalidState); return false; } true } }
--- a/servo/components/style/stylesheets/supports_rule.rs +++ b/servo/components/style/stylesheets/supports_rule.rs @@ -140,17 +140,17 @@ impl SupportsCondition { } } /// Parses a functional supports condition. fn parse_functional<'i, 't>( function: &str, input: &mut Parser<'i, 't>, ) -> Result<Self, ParseError<'i>> { - match_ignore_ascii_case!{ function, + match_ignore_ascii_case! { function, // Although this is an internal syntax, it is not necessary // to check parsing context as far as we accept any // unexpected token as future syntax, and evaluate it to // false when not in chrome / ua sheet. // See https://drafts.csswg.org/css-conditional-3/#general_enclosed "-moz-bool-pref" => { let name = { let name = input.expect_string()?; @@ -345,19 +345,18 @@ impl RawSelector { let selector = Selector::<SelectorImpl>::parse(&parser, input) .map_err(|_| input.new_custom_error(()))?; #[cfg(feature = "gecko")] { use crate::selector_parser::PseudoElement; use selectors::parser::Component; - let has_any_unknown_webkit_pseudo = selector.has_pseudo_element() && selector - .iter_raw_match_order() - .any(|component| { + let has_any_unknown_webkit_pseudo = selector.has_pseudo_element() && + selector.iter_raw_match_order().any(|component| { matches!( *component, Component::PseudoElement(PseudoElement::UnknownWebkit(..)) ) }); if has_any_unknown_webkit_pseudo { return Err(input.new_custom_error(())); }
--- a/servo/components/style/stylesheets/viewport_rule.rs +++ b/servo/components/style/stylesheets/viewport_rule.rs @@ -2,29 +2,29 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! The [`@viewport`][at] at-rule and [`meta`][meta] element. //! //! [at]: https://drafts.csswg.org/css-device-adapt/#atviewport-rule //! [meta]: https://drafts.csswg.org/css-device-adapt/#viewport-meta -use app_units::Au; use crate::context::QuirksMode; use crate::error_reporting::ContextualParseError; use crate::font_metrics::get_metrics_provider_for_product; use crate::media_queries::Device; use crate::parser::ParserContext; use crate::properties::StyleBuilder; use crate::rule_cache::RuleCacheConditions; use crate::shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard}; use crate::str::CssStringWriter; use crate::stylesheets::{Origin, StylesheetInDocument}; use crate::values::computed::{Context, ToComputedValue}; use crate::values::specified::{LengthOrPercentageOrAuto, NoCalcLength, ViewportPercentageLength}; +use app_units::Au; use cssparser::CowRcStr; use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; use euclid::TypedSize2D; use selectors::parser::SelectorParseErrorKind; use std::borrow::Cow; use std::cell::RefCell; use std::fmt::{self, Write}; use std::iter::Enumerate;
--- a/servo/components/style/stylist.rs +++ b/servo/components/style/stylist.rs @@ -12,17 +12,17 @@ use crate::font_metrics::FontMetricsProv #[cfg(feature = "gecko")] use crate::gecko_bindings::structs::{ServoStyleSetSizes, StyleRuleInclusion}; use crate::invalidation::element::invalidation_map::InvalidationMap; use crate::invalidation::media_queries::{EffectiveMediaQueryResults, ToMediaListKey}; use crate::media_queries::Device; use crate::properties::{self, CascadeMode, ComputedValues}; use crate::properties::{AnimationRules, PropertyDeclarationBlock}; use crate::rule_cache::{RuleCache, RuleCacheConditions}; -use crate::rule_collector::{RuleCollector, containing_shadow_ignoring_svg_use}; +use crate::rule_collector::{containing_shadow_ignoring_svg_use, RuleCollector}; use crate::rule_tree::{CascadeLevel, RuleTree, ShadowCascadeOrder, StrongRuleNode, StyleSource}; use crate::selector_map::{PrecomputedHashMap, PrecomputedHashSet, SelectorMap, SelectorMapEntry}; use crate::selector_parser::{PerPseudoElementMap, PseudoElement, SelectorImpl, SnapshotMap}; use crate::shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; use crate::stylesheet_set::{DataValidity, DocumentStylesheetSet, SheetRebuildKind}; use crate::stylesheet_set::{DocumentStylesheetFlusher, SheetCollectionFlusher}; use crate::stylesheets::keyframes_rule::KeyframesAnimation; use crate::stylesheets::viewport_rule::{self, MaybeNew, ViewportRule}; @@ -350,20 +350,17 @@ pub struct Stylist { /// Viewport constraints based on the current device. viewport_constraints: Option<ViewportConstraints>, /// The list of stylesheets. stylesheets: StylistStylesheetSet, /// If true, the quirks-mode stylesheet is applied. - #[cfg_attr( - feature = "servo", - ignore_malloc_size_of = "defined in selectors" - )] + #[cfg_attr(feature = "servo", ignore_malloc_size_of = "defined in selectors")] quirks_mode: QuirksMode, /// Selector maps for all of the style sheets in the stylist, after /// evalutaing media rules against the current device, split out per /// cascade level. cascade_data: DocumentCascadeData, /// Whether author styles are enabled. @@ -1567,38 +1564,36 @@ impl<'a> SelectorVisitor for StylistSele // NOTE(emilio): This works properly right now because we can't store // complex selectors in nested selectors, otherwise we may need to // rethink this. // // Also, note that this call happens before we visit any of the simple // selectors in the next ComplexSelector, so we can use this to skip // looking at them. - self.passed_rightmost_selector = - self.passed_rightmost_selector || - !matches!(combinator, None | Some(Combinator::PseudoElement)); + self.passed_rightmost_selector = self.passed_rightmost_selector || + !matches!(combinator, None | Some(Combinator::PseudoElement)); true } fn visit_attribute_selector( &mut self, _ns: &NamespaceConstraint<&Namespace>, name: &LocalName, lower_name: &LocalName, ) -> bool { self.attribute_dependencies.insert(name.clone()); self.attribute_dependencies.insert(lower_name.clone()); true } fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool { - self.needs_revalidation = - self.needs_revalidation || - component_needs_revalidation(s, self.passed_rightmost_selector); + self.needs_revalidation = self.needs_revalidation || + component_needs_revalidation(s, self.passed_rightmost_selector); match *s { Component::NonTSPseudoClass(ref p) => { self.state_dependencies.insert(p.state_flag()); self.document_state_dependencies .insert(p.document_state_flag()); }, Component::ID(ref id) if !self.passed_rightmost_selector => { @@ -2021,20 +2016,20 @@ impl CascadeData { self.effective_media_query_results.saw_effective(media_rule); } }, CssRule::Keyframes(ref keyframes_rule) => { let keyframes_rule = keyframes_rule.read_with(guard); debug!("Found valid keyframes rule: {:?}", *keyframes_rule); // Don't let a prefixed keyframes animation override a non-prefixed one. - let needs_insertion = keyframes_rule.vendor_prefix.is_none() || self - .animations - .get(keyframes_rule.name.as_atom()) - .map_or(true, |rule| rule.vendor_prefix.is_some()); + let needs_insertion = keyframes_rule.vendor_prefix.is_none() || + self.animations + .get(keyframes_rule.name.as_atom()) + .map_or(true, |rule| rule.vendor_prefix.is_some()); if needs_insertion { let animation = KeyframesAnimation::from_keyframes( &keyframes_rule.keyframes, keyframes_rule.vendor_prefix.clone(), guard, ); debug!("Found valid keyframe animation: {:?}", animation); self.animations
--- a/servo/components/style/traversal.rs +++ b/servo/components/style/traversal.rs @@ -203,21 +203,21 @@ pub trait DomTraversal<E: TElement>: Syn el, traversal_flags, data ); // In case of animation-only traversal we need to traverse the element // if the element has animation only dirty descendants bit, // animation-only restyle hint or recascade. if traversal_flags.for_animation_only() { return data.map_or(false, |d| d.has_styles()) && - (el.has_animation_only_dirty_descendants() || data - .as_ref() - .unwrap() - .hint - .has_animation_hint_or_recascade()); + (el.has_animation_only_dirty_descendants() || + data.as_ref() + .unwrap() + .hint + .has_animation_hint_or_recascade()); } // Non-incremental layout visits every node. if is_servo_nonincremental_layout() { return true; } // Unwrap the data. @@ -511,19 +511,18 @@ pub fn recalc_style_at<E, D, F>( // Additionally, there are a few scenarios where we avoid traversing the // subtree even if descendant styles are out of date. These cases are // enumerated in should_cull_subtree(). let mut traverse_children = has_dirty_descendants_for_this_restyle || !propagated_hint.is_empty() || !child_cascade_requirement.can_skip_cascade() || is_servo_nonincremental_layout(); - traverse_children = - traverse_children && - !traversal.should_cull_subtree(context, element, &data, is_initial_style); + traverse_children = traverse_children && + !traversal.should_cull_subtree(context, element, &data, is_initial_style); // Examine our children, and enqueue the appropriate ones for traversal. if traverse_children { note_children::<E, D, F>( context, element, data, propagated_hint,
--- a/servo/components/style/values/animated/mod.rs +++ b/servo/components/style/values/animated/mod.rs @@ -3,24 +3,24 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Animated values. //! //! Some values, notably colors, cannot be interpolated directly with their //! computed values and need yet another intermediate representation. This //! module's raison d'ĂŞtre is to ultimately contain all these types. -use app_units::Au; use crate::properties::PropertyId; use crate::values::computed::length::CalcLengthOrPercentage; use crate::values::computed::url::ComputedUrl; use crate::values::computed::Angle as ComputedAngle; use crate::values::computed::Image; +use crate::values::specified::SVGPathData; use crate::values::CSSFloat; -use crate::values::specified::SVGPathData; +use app_units::Au; use euclid::{Point2D, Size2D}; use smallvec::SmallVec; use std::cmp; pub mod color; pub mod effects; mod font; mod length;
--- a/servo/components/style/values/computed/border.rs +++ b/servo/components/style/values/computed/border.rs @@ -1,33 +1,34 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Computed types for CSS values related to borders. -use app_units::Au; -use crate::values::generics::NonNegative; -use crate::values::computed::length::{NonNegativeLengthOrPercentage, NonNegativeLength}; +use crate::values::computed::length::{NonNegativeLength, NonNegativeLengthOrPercentage}; use crate::values::computed::{NonNegativeNumber, NonNegativeNumberOrPercentage}; use crate::values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use crate::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; use crate::values::generics::border::BorderImageSlice as GenericBorderImageSlice; use crate::values::generics::border::BorderRadius as GenericBorderRadius; use crate::values::generics::border::BorderSpacing as GenericBorderSpacing; use crate::values::generics::rect::Rect; use crate::values::generics::size::Size; +use crate::values::generics::NonNegative; +use app_units::Au; pub use crate::values::specified::border::BorderImageRepeat; /// A computed value for the `border-image-width` property. pub type BorderImageWidth = Rect<BorderImageSideWidth>; /// A computed value for a single side of a `border-image-width` property. -pub type BorderImageSideWidth = GenericBorderImageSideWidth<NonNegativeLengthOrPercentage, NonNegativeNumber>; +pub type BorderImageSideWidth = + GenericBorderImageSideWidth<NonNegativeLengthOrPercentage, NonNegativeNumber>; /// A computed value for the `border-image-slice` property. pub type BorderImageSlice = GenericBorderImageSlice<NonNegativeNumberOrPercentage>; /// A computed value for the `border-radius` property. pub type BorderRadius = GenericBorderRadius<NonNegativeLengthOrPercentage>; /// A computed value for the `border-*-radius` longhand properties.
--- a/servo/components/style/values/computed/font.rs +++ b/servo/components/style/values/computed/font.rs @@ -1,29 +1,29 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Computed values for font properties -use app_units::Au; -use byteorder::{BigEndian, ByteOrder}; #[cfg(feature = "gecko")] use crate::gecko_bindings::sugar::refptr::RefPtr; #[cfg(feature = "gecko")] use crate::gecko_bindings::{bindings, structs}; use crate::values::animated::{ToAnimatedValue, ToAnimatedZero}; use crate::values::computed::{Angle, Context, Integer, NonNegativeLength, NonNegativePercentage}; use crate::values::computed::{Number, Percentage, ToComputedValue}; use crate::values::generics::font as generics; use crate::values::generics::font::{FeatureTagValue, FontSettings, VariationValue}; use crate::values::specified::font::{self as specified, MAX_FONT_WEIGHT, MIN_FONT_WEIGHT}; use crate::values::specified::length::{FontBaseSize, NoCalcLength}; use crate::values::CSSFloat; use crate::Atom; +use app_units::Au; +use byteorder::{BigEndian, ByteOrder}; use cssparser::{serialize_identifier, CssStringWriter, Parser}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use std::fmt::{self, Write}; use std::hash::{Hash, Hasher}; #[cfg(feature = "servo")] use std::slice; use style_traits::{CssWriter, ParseError, ToCss};
--- a/servo/components/style/values/computed/length.rs +++ b/servo/components/style/values/computed/length.rs @@ -1,25 +1,25 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! `<length>` computed values, and related ones. use super::{Context, Number, Percentage, ToComputedValue}; -use app_units::Au; use crate::values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; use crate::values::generics::length::MaxLength as GenericMaxLength; use crate::values::generics::length::MozLength as GenericMozLength; use crate::values::generics::transform::IsZeroLength; use crate::values::generics::NonNegative; use crate::values::specified::length::ViewportPercentageLength; use crate::values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; use crate::values::{specified, Auto, CSSFloat, Either, IsAuto, Normal}; +use app_units::Au; use ordered_float::NotNan; use std::fmt::{self, Write}; use std::ops::{Add, Neg}; use style_traits::values::specified::AllowedNumericType; use style_traits::{CssWriter, ToCss}; pub use super::image::Image; pub use crate::values::specified::url::UrlOrNone;
--- a/servo/components/style/values/computed/mod.rs +++ b/servo/components/style/values/computed/mod.rs @@ -541,17 +541,19 @@ impl From<GreaterThanOrEqualToOneNumber> pub enum NumberOrPercentage { Percentage(Percentage), Number(Number), } impl NumberOrPercentage { fn clamp_to_non_negative(self) -> Self { match self { - NumberOrPercentage::Percentage(p) => NumberOrPercentage::Percentage(p.clamp_to_non_negative()), + NumberOrPercentage::Percentage(p) => { + NumberOrPercentage::Percentage(p.clamp_to_non_negative()) + }, NumberOrPercentage::Number(n) => NumberOrPercentage::Number(n.max(0.)), } } } impl ToComputedValue for specified::NumberOrPercentage { type ComputedValue = NumberOrPercentage;
--- a/servo/components/style/values/generics/basic_shape.rs +++ b/servo/components/style/values/generics/basic_shape.rs @@ -286,21 +286,17 @@ where B: ComputeSquaredDistance, T: PartialEq, { fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { match (self, other) { ( &ShapeSource::Shape(ref this, ref this_box), &ShapeSource::Shape(ref other, ref other_box), - ) - if this_box == other_box => - { - this.compute_squared_distance(other) - }, + ) if this_box == other_box => this.compute_squared_distance(other), (&ShapeSource::Path(ref this), &ShapeSource::Path(ref other)) if this.fill == other.fill => { this.path.compute_squared_distance(&other.path) }, _ => Err(()), } }
--- a/servo/components/style/values/generics/font.rs +++ b/servo/components/style/values/generics/font.rs @@ -1,17 +1,17 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Generic types for font stuff. +use crate::parser::{Parse, ParserContext}; use app_units::Au; use byteorder::{BigEndian, ReadBytesExt}; -use crate::parser::{Parse, ParserContext}; use cssparser::Parser; use num_traits::One; use std::fmt::{self, Write}; use std::io::Cursor; use style_traits::{CssWriter, KeywordsCollectFn, ParseError}; use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; /// https://drafts.csswg.org/css-fonts-4/#feature-tag-value
--- a/servo/components/style/values/generics/text.rs +++ b/servo/components/style/values/generics/text.rs @@ -1,18 +1,18 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Generic types for text properties. -use app_units::Au; use crate::parser::ParserContext; use crate::values::animated::{Animate, Procedure, ToAnimatedZero}; use crate::values::distance::{ComputeSquaredDistance, SquaredDistance}; +use app_units::Au; use cssparser::Parser; use style_traits::ParseError; /// A generic value for the `initial-letter` property. #[derive( Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, )] pub enum InitialLetter<Number, Integer> {
--- a/servo/components/style/values/generics/transform.rs +++ b/servo/components/style/values/generics/transform.rs @@ -1,21 +1,21 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Generic types for CSS values that are related to transformations. -use app_units::Au; use crate::values::computed::length::Length as ComputedLength; use crate::values::computed::length::LengthOrPercentage as ComputedLengthOrPercentage; use crate::values::specified::angle::Angle as SpecifiedAngle; use crate::values::specified::length::Length as SpecifiedLength; use crate::values::specified::length::LengthOrPercentage as SpecifiedLengthOrPercentage; use crate::values::{computed, CSSFloat}; +use app_units::Au; use euclid::{self, Rect, Transform3D}; use num_traits::Zero; use std::fmt::{self, Write}; use style_traits::{CssWriter, ToCss}; /// A generic 2D transformation matrix. #[allow(missing_docs)] #[derive(
--- a/servo/components/style/values/mod.rs +++ b/servo/components/style/values/mod.rs @@ -88,20 +88,17 @@ pub fn serialize_percentage<W>(value: CS where W: Write, { (value * 100.).to_css(dest)?; dest.write_str("%") } /// Convenience void type to disable some properties and values through types. -#[cfg_attr( - feature = "servo", - derive(Deserialize, MallocSizeOf, Serialize) -)] +#[cfg_attr(feature = "servo", derive(Deserialize, MallocSizeOf, Serialize))] #[derive( Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss, )] pub enum Impossible {} // FIXME(nox): This should be derived but the derive code cannot cope // with uninhabited enums. impl ComputeSquaredDistance for Impossible {
--- a/servo/components/style/values/specified/angle.rs +++ b/servo/components/style/values/specified/angle.rs @@ -188,17 +188,17 @@ impl Angle { } => { Angle::parse_dimension(value, unit, /* from_calc = */ false) }, Token::Number { value, .. } if value == 0. => match allow_unitless_zero { AllowUnitlessZeroAngle::Yes => Ok(Angle::zero()), AllowUnitlessZeroAngle::No => Err(()), }, Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { - return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)) + return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)); }, _ => Err(()), } .map_err(|()| input.new_unexpected_token_error(token.clone())) } } impl SpecifiedValueInfo for Angle {}
--- a/servo/components/style/values/specified/basic_shape.rs +++ b/servo/components/style/values/specified/basic_shape.rs @@ -11,18 +11,18 @@ use crate::parser::{Parse, ParserContext use crate::values::generics::basic_shape as generic; use crate::values::generics::basic_shape::{GeometryBox, Path, PolygonCoord}; use crate::values::generics::basic_shape::{ShapeBox, ShapeSource}; use crate::values::generics::rect::Rect; use crate::values::specified::border::BorderRadius; use crate::values::specified::image::Image; use crate::values::specified::position::{HorizontalPosition, Position, VerticalPosition}; use crate::values::specified::url::SpecifiedUrl; +use crate::values::specified::SVGPathData; use crate::values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage}; -use crate::values::specified::SVGPathData; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; /// A specified alias for FillRule. pub use crate::values::generics::basic_shape::FillRule; /// A specified clipping shape.
--- a/servo/components/style/values/specified/border.rs +++ b/servo/components/style/values/specified/border.rs @@ -8,17 +8,17 @@ use crate::parser::{Parse, ParserContext use crate::values::computed::{self, Context, ToComputedValue}; use crate::values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; use crate::values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; use crate::values::generics::border::BorderImageSlice as GenericBorderImageSlice; use crate::values::generics::border::BorderRadius as GenericBorderRadius; use crate::values::generics::border::BorderSpacing as GenericBorderSpacing; use crate::values::generics::rect::Rect; use crate::values::generics::size::Size; -use crate::values::specified::length::{NonNegativeLengthOrPercentage, NonNegativeLength}; +use crate::values::specified::length::{NonNegativeLength, NonNegativeLengthOrPercentage}; use crate::values::specified::{AllowQuirks, NonNegativeNumber, NonNegativeNumberOrPercentage}; use cssparser::Parser; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, ToCss}; /// A specified value for a single side of a `border-style` property. /// /// The order here corresponds to the integer values from the border conflict @@ -73,17 +73,18 @@ pub enum BorderSideWidth { /// `<length>` Length(NonNegativeLength), } /// A specified value for the `border-image-width` property. pub type BorderImageWidth = Rect<BorderImageSideWidth>; /// A specified value for a single side of a `border-image-width` property. -pub type BorderImageSideWidth = GenericBorderImageSideWidth<NonNegativeLengthOrPercentage, NonNegativeNumber>; +pub type BorderImageSideWidth = + GenericBorderImageSideWidth<NonNegativeLengthOrPercentage, NonNegativeNumber>; /// A specified value for the `border-image-slice` property. pub type BorderImageSlice = GenericBorderImageSlice<NonNegativeNumberOrPercentage>; /// A specified value for the `border-radius` property. pub type BorderRadius = GenericBorderRadius<NonNegativeLengthOrPercentage>; /// A specified value for the `border-*-radius` longhand properties. @@ -111,18 +112,17 @@ impl BorderSideWidth { } /// Parses, with quirks. pub fn parse_quirky<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result<Self, ParseError<'i>> { - if let Ok(length) = - input.try(|i| NonNegativeLength::parse_quirky(context, i, allow_quirks)) + if let Ok(length) = input.try(|i| NonNegativeLength::parse_quirky(context, i, allow_quirks)) { return Ok(BorderSideWidth::Length(length)); } try_match_ident_ignore_ascii_case! { input, "thin" => Ok(BorderSideWidth::Thin), "medium" => Ok(BorderSideWidth::Medium), "thick" => Ok(BorderSideWidth::Thick), }
--- a/servo/components/style/values/specified/box.rs +++ b/servo/components/style/values/specified/box.rs @@ -213,20 +213,17 @@ impl Display { #[cfg(feature = "gecko")] Display::InlineGrid => Display::Grid, #[cfg(feature = "gecko")] Display::WebkitInlineBox => Display::WebkitBox, // Special handling for contents and list-item on the root // element for Gecko. #[cfg(feature = "gecko")] - Display::Contents | Display::ListItem if _is_root_element => - { - Display::Block - }, + Display::Contents | Display::ListItem if _is_root_element => Display::Block, // These are not changed by blockification. Display::None | Display::Block | Display::Flex | Display::ListItem | Display::Table => { *self }, #[cfg(feature = "gecko")] Display::Contents | Display::FlowRoot | Display::Grid | Display::WebkitBox => *self, @@ -742,17 +739,19 @@ impl Parse for Contain { "content" if result.is_empty() => return Ok(Contain::CONTENT | Contain::CONTENT_BITS), "none" if result.is_empty() => return Ok(result), _ => None }; let flag = match flag { Some(flag) if !result.contains(flag) => flag, _ => { - return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name))) + return Err( + input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name)) + ); }, }; result.insert(flag); } if !result.is_empty() { Ok(result) } else { @@ -821,17 +820,17 @@ impl Parse for TransitionProperty { let id = match PropertyId::parse_ignoring_rule_type(&ident, context) { Ok(id) => id, Err(..) => { return Ok(TransitionProperty::Unsupported(CustomIdent::from_ident( location, ident, &["none"], - )?)) + )?)); }, }; Ok(match id.as_shorthand() { Ok(s) => TransitionProperty::Shorthand(s), Err(longhand_or_custom) => match longhand_or_custom { PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id), PropertyDeclarationId::Custom(custom) => TransitionProperty::Custom(custom.clone()), @@ -1304,17 +1303,17 @@ impl BreakBetween { #[inline] pub fn parse_legacy<'i>(input: &mut Parser<'i, '_>) -> Result<Self, ParseError<'i>> { let location = input.current_source_location(); let ident = input.expect_ident()?; let break_value = match BreakBetween::from_ident(ident) { Ok(v) => v, Err(()) => { return Err(location - .new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) + .new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); }, }; match break_value { BreakBetween::Always => Ok(BreakBetween::Page), BreakBetween::Auto | BreakBetween::Avoid | BreakBetween::Left | BreakBetween::Right => { Ok(break_value) }, BreakBetween::Page => {
--- a/servo/components/style/values/specified/calc.rs +++ b/servo/components/style/values/specified/calc.rs @@ -175,17 +175,17 @@ impl CalcNode { ( &Token::Dimension { value, ref unit, .. }, CalcUnit::LengthOrPercentage, ) => { return NoCalcLength::parse_dimension(context, value, unit) .map(CalcNode::Length) - .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) + .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); }, ( &Token::Dimension { value, ref unit, .. }, CalcUnit::Angle, ) => { return Angle::parse_dimension(value, unit, /* from_calc = */ true) @@ -199,17 +199,17 @@ impl CalcNode { CalcUnit::Time, ) => { return Time::parse_dimension(value, unit, /* from_calc = */ true) .map(CalcNode::Time) .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); }, (&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) | (&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => { - return Ok(CalcNode::Percentage(unit_value)) + return Ok(CalcNode::Percentage(unit_value)); }, (&Token::ParenthesisBlock, _) => {}, (&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {}, (t, _) => return Err(location.new_unexpected_token_error(t.clone())), } input.parse_nested_block(|i| CalcNode::parse(context, i, expected_unit)) }
--- a/servo/components/style/values/specified/counters.rs +++ b/servo/components/style/values/specified/counters.rs @@ -176,17 +176,17 @@ impl Parse for Content { })), _ => None }; match result { Some(result) => content.push(result?), None => { return Err(input.new_custom_error( StyleParseErrorKind::UnexpectedFunction(name.clone()), - )) + )); }, } }, Ok(Token::Ident(ref ident)) => { content.push(match_ignore_ascii_case! { &ident, "open-quote" => generics::ContentItem::OpenQuote, "close-quote" => generics::ContentItem::CloseQuote, "no-open-quote" => generics::ContentItem::NoOpenQuote,
--- a/servo/components/style/values/specified/font.rs +++ b/servo/components/style/values/specified/font.rs @@ -1,32 +1,32 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! Specified values for font properties -use app_units::Au; -use byteorder::{BigEndian, ByteOrder}; #[cfg(feature = "gecko")] use crate::gecko_bindings::bindings; use crate::parser::{Parse, ParserContext}; use crate::properties::longhands::system_font::SystemFont; use crate::values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle, SingleFontFamily}; use crate::values::computed::{font as computed, Length, NonNegativeLength}; use crate::values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage}; use crate::values::computed::{Context, ToComputedValue}; use crate::values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag}; use crate::values::generics::font::{KeywordSize, VariationValue}; use crate::values::generics::NonNegative; use crate::values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX}; use crate::values::specified::{AllowQuirks, Angle, Integer, LengthOrPercentage}; use crate::values::specified::{NoCalcLength, Number, Percentage}; use crate::values::CustomIdent; use crate::Atom; +use app_units::Au; +use byteorder::{BigEndian, ByteOrder}; use cssparser::{Parser, Token}; #[cfg(feature = "gecko")] use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use std::fmt::{self, Write}; use style_traits::values::SequenceWriter; use style_traits::{CssWriter, KeywordsCollectFn, ParseError}; use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss};
--- a/servo/components/style/values/specified/grid.rs +++ b/servo/components/style/values/specified/grid.rs @@ -17,21 +17,17 @@ use std::mem; use style_traits::{ParseError, StyleParseErrorKind}; /// Parse a single flexible length. pub fn parse_flex<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CSSFloat, ParseError<'i>> { let location = input.current_source_location(); match *input.next()? { Token::Dimension { value, ref unit, .. - } - if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive() => - { - Ok(value) - }, + } if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive() => Ok(value), ref t => Err(location.new_unexpected_token_error(t.clone())), } } impl Parse for TrackBreadth<LengthOrPercentage> { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>,
--- a/servo/components/style/values/specified/image.rs +++ b/servo/components/style/values/specified/image.rs @@ -257,17 +257,17 @@ impl Parse for Gradient { }); }, _ => None, }; let (shape, repeating, mut compat_mode) = match result { Some(result) => result, None => { - return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(func))) + return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(func))); }, }; #[cfg(feature = "gecko")] { use crate::gecko_bindings::structs; if compat_mode == CompatMode::Moz && !unsafe { structs::StaticPrefs_sVarCache_layout_css_prefixes_gradients } @@ -787,17 +787,17 @@ impl LineDirection { // According to Gecko, `-moz-linear-gradient(to ...)` should serialize like // `linear-gradient(to ...)`. CompatMode::Moz if to_ident.is_ok() => *compat_mode = CompatMode::Modern, // There is no `to` keyword in webkit prefixed syntax. If it's consumed, // parsing should throw an error. CompatMode::WebKit if to_ident.is_ok() => { return Err( i.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("to".into())) - ) + ); }, _ => {}, } #[cfg(feature = "gecko")] { // `-moz-` prefixed linear gradient can be both Angle and Position. if *compat_mode == CompatMode::Moz {
--- a/servo/components/style/values/specified/length.rs +++ b/servo/components/style/values/specified/length.rs @@ -2,26 +2,26 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! [Length values][length]. //! //! [length]: https://drafts.csswg.org/css-values/#lengths use super::{AllowQuirks, Number, Percentage, ToComputedValue}; -use app_units::Au; use crate::font_metrics::FontMetricsQueryResult; use crate::parser::{Parse, ParserContext}; use crate::values::computed::{self, CSSPixelLength, Context, ExtremumLength}; use crate::values::generics::length::MaxLength as GenericMaxLength; use crate::values::generics::length::MozLength as GenericMozLength; use crate::values::generics::transform::IsZeroLength; use crate::values::generics::NonNegative; use crate::values::specified::calc::CalcNode; use crate::values::{Auto, CSSFloat, Either, IsAuto, Normal}; +use app_units::Au; use cssparser::{Parser, Token}; use euclid::Size2D; use std::cmp; use std::ops::{Add, Mul}; use style_traits::values::specified::AllowedNumericType; use style_traits::{ParseError, SpecifiedValueInfo, StyleParseErrorKind}; pub use super::image::{ColorStop, EndingShape as GradientEndingShape, Gradient}; @@ -596,22 +596,20 @@ impl Length { ) -> Result<Self, ParseError<'i>> { // FIXME: remove early returns when lifetimes are non-lexical { let location = input.current_source_location(); let token = input.next()?; match *token { Token::Dimension { value, ref unit, .. - } - if num_context.is_ok(context.parsing_mode, value) => - { + } if num_context.is_ok(context.parsing_mode, value) => { return NoCalcLength::parse_dimension(context, value, unit) .map(Length::NoCalc) - .map_err(|()| location.new_unexpected_token_error(token.clone())) + .map_err(|()| location.new_unexpected_token_error(token.clone())); }, Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { if value != 0. && !context.parsing_mode.allows_unitless_lengths() && !allow_quirks.allowed(context.quirks_mode) { return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } @@ -722,17 +720,21 @@ impl NonNegativeLength { /// Parses a non-negative length, optionally with quirks. #[inline] pub fn parse_quirky<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, allow_quirks: AllowQuirks, ) -> Result<Self, ParseError<'i>> { - Ok(NonNegative(Length::parse_non_negative_quirky(context, input, allow_quirks)?)) + Ok(NonNegative(Length::parse_non_negative_quirky( + context, + input, + allow_quirks, + )?)) } } /// Either a NonNegativeLength or the `auto` keyword. pub type NonNegativeLengthOrAuto = Either<NonNegativeLength, Auto>; /// A length or a percentage value. #[allow(missing_docs)] @@ -795,30 +797,28 @@ impl LengthOrPercentage { ) -> Result<Self, ParseError<'i>> { // FIXME: remove early returns when lifetimes are non-lexical { let location = input.current_source_location(); let token = input.next()?; match *token { Token::Dimension { value, ref unit, .. - } - if num_context.is_ok(context.parsing_mode, value) => - { + } if num_context.is_ok(context.parsing_mode, value) => { return NoCalcLength::parse_dimension(context, value, unit) .map(LengthOrPercentage::Length) - .map_err(|()| location.new_unexpected_token_error(token.clone())) + .map_err(|()| location.new_unexpected_token_error(token.clone())); }, Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { return Ok(LengthOrPercentage::Percentage(computed::Percentage( unit_value, - ))) - }, + ))); + } Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { if value != 0. && !context.parsing_mode.allows_unitless_lengths() && !allow_quirks.allowed(context.quirks_mode) { return Err(location.new_unexpected_token_error(token.clone())); } else { return Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value))); @@ -927,43 +927,41 @@ impl LengthOrPercentageOrAuto { ) -> Result<Self, ParseError<'i>> { // FIXME: remove early returns when lifetimes are non-lexical { let location = input.current_source_location(); let token = input.next()?; match *token { Token::Dimension { value, ref unit, .. - } - if num_context.is_ok(context.parsing_mode, value) => - { + } if num_context.is_ok(context.parsing_mode, value) => { return NoCalcLength::parse_dimension(context, value, unit) .map(LengthOrPercentageOrAuto::Length) - .map_err(|()| location.new_unexpected_token_error(token.clone())) + .map_err(|()| location.new_unexpected_token_error(token.clone())); }, Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { return Ok(LengthOrPercentageOrAuto::Percentage(computed::Percentage( unit_value, - ))) - }, + ))); + } Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { if value != 0. && !context.parsing_mode.allows_unitless_lengths() && !allow_quirks.allowed(context.quirks_mode) { return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } return Ok(LengthOrPercentageOrAuto::Length(NoCalcLength::Absolute( AbsoluteLength::Px(value), ))); }, Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => { - return Ok(LengthOrPercentageOrAuto::Auto) + return Ok(LengthOrPercentageOrAuto::Auto); }, Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, _ => return Err(location.new_unexpected_token_error(token.clone())), } } let calc = input.parse_nested_block(|i| { CalcNode::parse_length_or_percentage(context, i, num_context) @@ -1093,44 +1091,42 @@ impl LengthOrPercentageOrNone { ) -> Result<Self, ParseError<'i>> { // FIXME: remove early returns when lifetimes are non-lexical { let location = input.current_source_location(); let token = input.next()?; match *token { Token::Dimension { value, ref unit, .. - } - if num_context.is_ok(context.parsing_mode, value) => - { + } if num_context.is_ok(context.parsing_mode, value) => { return NoCalcLength::parse_dimension(context, value, unit) .map(LengthOrPercentageOrNone::Length) - .map_err(|()| location.new_unexpected_token_error(token.clone())) + .map_err(|()| location.new_unexpected_token_error(token.clone())); }, Token::Percentage { unit_value, .. } if num_context.is_ok(context.parsing_mode, unit_value) => { return Ok(LengthOrPercentageOrNone::Percentage(computed::Percentage( unit_value, - ))) - }, + ))); + } Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { if value != 0. && !context.parsing_mode.allows_unitless_lengths() && !allow_quirks.allowed(context.quirks_mode) { return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); } return Ok(LengthOrPercentageOrNone::Length(NoCalcLength::Absolute( AbsoluteLength::Px(value), ))); }, Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => { - return Ok(LengthOrPercentageOrNone::None) + return Ok(LengthOrPercentageOrNone::None); }, _ => return Err(location.new_unexpected_token_error(token.clone())), } } let calc = input.parse_nested_block(|i| { CalcNode::parse_length_or_percentage(context, i, num_context) })?;
--- a/servo/components/style/values/specified/mod.rs +++ b/servo/components/style/values/specified/mod.rs @@ -133,17 +133,17 @@ fn parse_number_with_clamping_mode<'i, ' ) -> Result<Number, ParseError<'i>> { let location = input.current_source_location(); // FIXME: remove early returns when lifetimes are non-lexical match *input.next()? { Token::Number { value, .. } if clamping_mode.is_ok(context.parsing_mode, value) => { return Ok(Number { value: value.min(f32::MAX).max(f32::MIN), calc_clamping_mode: None, - }) + }); }, Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, ref t => return Err(location.new_unexpected_token_error(t.clone())), } let result = input.parse_nested_block(|i| CalcNode::parse_number(context, i))?; Ok(Number { @@ -370,17 +370,19 @@ impl NonNegativeNumberOrPercentage { } } impl Parse for NonNegativeNumberOrPercentage { fn parse<'i, 't>( context: &ParserContext, input: &mut Parser<'i, 't>, ) -> Result<Self, ParseError<'i>> { - Ok(NonNegative(NumberOrPercentage::parse_non_negative(context, input)?)) + Ok(NonNegative(NumberOrPercentage::parse_non_negative( + context, input, + )?)) } } #[allow(missing_docs)] #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, ToCss)] pub struct Opacity(Number); impl Parse for Opacity { @@ -823,17 +825,17 @@ impl Attr { }; let prefix_and_ns = if let Some(ns) = first { let prefix = Prefix::from(ns.as_ref()); let ns = match get_namespace_for_prefix(&prefix, context) { Some(ns) => ns, None => { return Err(location - .new_custom_error(StyleParseErrorKind::UnspecifiedError)) + .new_custom_error(StyleParseErrorKind::UnspecifiedError)); }, }; Some((prefix, ns)) } else { None }; return Ok(Attr { namespace: prefix_and_ns,
--- a/servo/components/style/values/specified/source_size_list.rs +++ b/servo/components/style/values/specified/source_size_list.rs @@ -1,21 +1,21 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ //! https://html.spec.whatwg.org/multipage/#source-size-list -use app_units::Au; #[cfg(feature = "gecko")] use crate::gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; use crate::media_queries::{Device, MediaCondition}; use crate::parser::{Parse, ParserContext}; use crate::values::computed::{self, ToComputedValue}; use crate::values::specified::{Length, NoCalcLength, ViewportPercentageLength}; +use app_units::Au; use cssparser::{Delimiter, Parser, Token}; use selectors::context::QuirksMode; use style_traits::ParseError; /// A value for a `<source-size>`: /// /// https://html.spec.whatwg.org/multipage/#source-size #[derive(Debug)] @@ -113,17 +113,17 @@ impl SourceSizeList { SourceSizeOrLength::parse(context, input) }); match result { Ok(SourceSizeOrLength::Length(value)) => { return Self { source_sizes, value: Some(value), - } + }; }, Ok(SourceSizeOrLength::SourceSize(source_size)) => { source_sizes.push(source_size); }, Err(..) => {}, } match input.next() {
--- a/servo/components/style/values/specified/text.rs +++ b/servo/components/style/values/specified/text.rs @@ -86,18 +86,17 @@ impl Parse for LineHeight { if let Ok(nlop) = input.try(|i| NonNegativeLengthOrPercentage::parse(context, i)) { return Ok(GenericLineHeight::Length(nlop)); } let location = input.current_source_location(); let ident = input.expect_ident()?; match ident { ref ident if ident.eq_ignore_ascii_case("normal") => Ok(GenericLineHeight::Normal), #[cfg(feature = "gecko")] - ref ident if ident.eq_ignore_ascii_case("-moz-block-height") => - { + ref ident if ident.eq_ignore_ascii_case("-moz-block-height") => { Ok(GenericLineHeight::MozBlockHeight) }, ident => { Err(location .new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) }, } }
--- a/servo/components/style/values/specified/time.rs +++ b/servo/components/style/values/specified/time.rs @@ -87,22 +87,20 @@ impl Time { match input.next() { // Note that we generally pass ParserContext to is_ok() to check // that the ParserMode of the ParserContext allows all numeric // values for SMIL regardless of clamping_mode, but in this Time // value case, the value does not animate for SMIL at all, so we use // ParsingMode::DEFAULT directly. Ok(&Token::Dimension { value, ref unit, .. - }) - if clamping_mode.is_ok(ParsingMode::DEFAULT, value) => - { + }) if clamping_mode.is_ok(ParsingMode::DEFAULT, value) => { return Time::parse_dimension(value, unit, /* from_calc = */ false) .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); - } + }, Ok(&Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {}, Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), Err(e) => return Err(e.into()), } match input.parse_nested_block(|i| CalcNode::parse_time(context, i)) { Ok(time) if clamping_mode.is_ok(ParsingMode::DEFAULT, time.seconds) => Ok(time), _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), }
--- a/servo/components/style_derive/cg.rs +++ b/servo/components/style_derive/cg.rs @@ -24,17 +24,17 @@ where F: FnMut(BindingInfo) -> TokenStream, { let mut s = synstructure::Structure::new(input); s.variants_mut().iter_mut().for_each(|v| { v.bind_with(|_| bind_style); }); s.each_variant(|variant| { let (mapped, mapped_fields) = value(variant, "mapped"); - let fields_pairs = variant.bindings().into_iter().zip(mapped_fields); + let fields_pairs = variant.bindings().iter().zip(mapped_fields); let mut computations = quote!(); computations.append_all(fields_pairs.map(|(field, mapped_field)| { let expr = f(field.clone()); quote! { let #mapped_field = #expr; } })); computations.append_all(mapped); Some(computations) }) @@ -167,19 +167,17 @@ where } } fn path_to_ident(path: &Path) -> Option<&Ident> { match *path { Path { leading_colon: None, ref segments, - } - if segments.len() == 1 => - { + } if segments.len() == 1 => { if segments[0].arguments.is_empty() { Some(&segments[0].ident) } else { None } }, _ => None, } @@ -232,26 +230,26 @@ pub fn ref_pattern<'a>( variant: &'a VariantInfo, prefix: &str, ) -> (TokenStream, Vec<BindingInfo<'a>>) { let mut v = variant.clone(); v.bind_with(|_| BindStyle::Ref); v.bindings_mut().iter_mut().for_each(|b| { b.binding = Ident::new(&format!("{}_{}", b.binding, prefix), Span::call_site()) }); - (v.pat(), v.bindings().iter().cloned().collect()) + (v.pat(), v.bindings().to_vec()) } pub fn value<'a>(variant: &'a VariantInfo, prefix: &str) -> (TokenStream, Vec<BindingInfo<'a>>) { let mut v = variant.clone(); v.bindings_mut().iter_mut().for_each(|b| { b.binding = Ident::new(&format!("{}_{}", b.binding, prefix), Span::call_site()) }); v.bind_with(|_| BindStyle::Move); - (v.pat(), v.bindings().iter().cloned().collect()) + (v.pat(), v.bindings().to_vec()) } /// Transforms "FooBar" to "foo-bar". /// /// If the first Camel segment is "Moz", "Webkit", or "Servo", the result string /// is prepended with "-". pub fn to_css_identifier(mut camel_case: &str) -> String { camel_case = camel_case.trim_end_matches('_');
--- a/servo/components/style_derive/parse.rs +++ b/servo/components/style_derive/parse.rs @@ -31,37 +31,37 @@ pub fn derive(input: DeriveInput) -> Tok let parse_attrs = cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast()); if css_variant_attrs.skip { return match_body; } let identifier = cg::to_css_identifier( &css_variant_attrs .keyword - .unwrap_or(variant.ast().ident.to_string()), + .unwrap_or_else(|| variant.ast().ident.to_string()), ); let ident = &variant.ast().ident; saw_condition |= parse_attrs.condition.is_some(); let condition = match parse_attrs.condition { Some(ref p) => quote! { if #p(context) }, - None => quote!{}, + None => quote! {}, }; let mut body = quote! { #match_body #identifier #condition => Ok(#name::#ident), }; let aliases = match parse_attrs.aliases { Some(aliases) => aliases, None => return body, }; - for alias in aliases.split(",") { + for alias in aliases.split(',') { body = quote! { #body #alias #condition => Ok(#name::#ident), }; } body });
--- a/servo/components/style_derive/specified_value_info.rs +++ b/servo/components/style_derive/specified_value_info.rs @@ -35,56 +35,54 @@ pub fn derive(mut input: DeriveInput) -> for v in e.variants.iter() { let css_attrs = cg::parse_variant_attrs::<CssVariantAttrs>(&v); let info_attrs = cg::parse_variant_attrs::<ValueInfoVariantAttrs>(&v); let parse_attrs = cg::parse_variant_attrs::<ParseVariantAttrs>(&v); if css_attrs.skip { continue; } if let Some(aliases) = parse_attrs.aliases { - for alias in aliases.split(",") { + for alias in aliases.split(',') { values.push(alias.to_string()); } } if let Some(other_values) = info_attrs.other_values { - for value in other_values.split(",") { + for value in other_values.split(',') { values.push(value.to_string()); } } let ident = &v.ident; let variant_name = || cg::to_css_identifier(&ident.to_string()); if info_attrs.starts_with_keyword { values.push(variant_name()); continue; } if let Some(keyword) = css_attrs.keyword { values.push(keyword); continue; } if let Some(function) = css_attrs.function { values.push(function.explicit().unwrap_or_else(variant_name)); - } else { - if !derive_struct_fields(&v.fields, &mut types, &mut values) { - values.push(variant_name()); - } + } else if !derive_struct_fields(&v.fields, &mut types, &mut values) { + values.push(variant_name()); } } }, Data::Struct(ref s) => { if !derive_struct_fields(&s.fields, &mut types, &mut values) { values.push(input_name()); } }, Data::Union(_) => unreachable!("union is not supported"), } } let info_attrs = cg::parse_input_attrs::<ValueInfoInputAttrs>(&input); if let Some(other_values) = info_attrs.other_values { - for value in other_values.split(",") { + for value in other_values.split(',') { values.push(value.to_string()); } } let mut types_value = quote!(0); types_value.append_all(types.iter().map(|ty| { quote! { | <#ty as style_traits::SpecifiedValueInfo>::SUPPORTED_TYPES @@ -138,17 +136,17 @@ fn derive_struct_fields<'a>( let fields = match *fields { Fields::Unit => return false, Fields::Named(ref fields) => fields.named.iter(), Fields::Unnamed(ref fields) => fields.unnamed.iter(), }; types.extend(fields.filter_map(|field| { let info_attrs = cg::parse_field_attrs::<ValueInfoFieldAttrs>(field); if let Some(other_values) = info_attrs.other_values { - for value in other_values.split(",") { + for value in other_values.split(',') { values.push(value.to_string()); } } let css_attrs = cg::parse_field_attrs::<CssFieldAttrs>(field); if css_attrs.represents_keyword { let ident = field .ident .as_ref()
--- a/servo/components/style_derive/to_animated_zero.rs +++ b/servo/components/style_derive/to_animated_zero.rs @@ -23,17 +23,17 @@ pub fn derive(mut input: syn::DeriveInpu } let to_body = synstructure::Structure::new(&input).each_variant(|variant| { let attrs = cg::parse_variant_attrs_from_ast::<AnimationVariantAttrs>(&variant.ast()); if attrs.error { return Some(quote! { Err(()) }); } let (mapped, mapped_bindings) = cg::value(variant, "mapped"); - let bindings_pairs = variant.bindings().into_iter().zip(mapped_bindings); + let bindings_pairs = variant.bindings().iter().zip(mapped_bindings); let mut computations = quote!(); computations.append_all(bindings_pairs.map(|(binding, mapped_binding)| { let field_attrs = cg::parse_field_attrs::<AnimationFieldAttrs>(&binding.ast()); if field_attrs.constant { quote! { let #mapped_binding = std::clone::Clone::clone(#binding); } } else {
--- a/servo/components/style_traits/lib.rs +++ b/servo/components/style_traits/lib.rs @@ -43,20 +43,17 @@ use servo_atoms::Atom; /// This unit corresponds to the smallest addressable element of the display hardware. #[cfg(not(feature = "servo"))] #[derive(Clone, Copy, Debug)] pub enum DevicePixel {} /// Represents a mobile style pinch zoom factor. /// TODO(gw): Once WR supports pinch zoom, use a type directly from webrender_api. #[derive(Clone, Copy, Debug, PartialEq)] -#[cfg_attr( - feature = "servo", - derive(Deserialize, Serialize, MallocSizeOf) -)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))] pub struct PinchZoomFactor(f32); impl PinchZoomFactor { /// Construct a new pinch zoom factor. pub fn new(scale: f32) -> PinchZoomFactor { PinchZoomFactor(scale) }
--- a/servo/components/style_traits/viewport.rs +++ b/servo/components/style_traits/viewport.rs @@ -23,20 +23,17 @@ define_css_keyword_enum! { Landscape = "landscape", } } /// A set of viewport descriptors: /// /// <https://drafts.csswg.org/css-device-adapt/#viewport-desc> #[derive(Clone, Debug, PartialEq)] -#[cfg_attr( - feature = "servo", - derive(Deserialize, Serialize, MallocSizeOf) -)] +#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))] pub struct ViewportConstraints { /// Width and height: /// * https://drafts.csswg.org/css-device-adapt/#width-desc /// * https://drafts.csswg.org/css-device-adapt/#height-desc pub size: TypedSize2D<f32, CSSPixel>, /// <https://drafts.csswg.org/css-device-adapt/#zoom-desc> pub initial_zoom: PinchZoomFactor, /// <https://drafts.csswg.org/css-device-adapt/#min-max-width-desc>
--- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -25,17 +25,16 @@ use style::context::{CascadeInputs, Quir use style::counter_style; use style::data::{self, ElementStyles}; use style::dom::{ShowSubtreeData, TDocument, TElement, TNode}; use style::driver; use style::element_state::{DocumentState, ElementState}; use style::error_reporting::{ContextualParseError, ParseErrorReporter}; use style::font_metrics::{get_metrics_provider_for_product, FontMetricsProvider}; use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl}; -use style::gecko::global_style_data::{GlobalStyleData, GLOBAL_STYLE_DATA, STYLE_THREAD_POOL}; use style::gecko::restyle_damage::GeckoRestyleDamage; use style::gecko::selector_parser::{NonTSPseudoClass, PseudoElement}; use style::gecko::traversal::RecalcStyleOnly; use style::gecko::url::CssUrlData; use style::gecko::wrapper::{GeckoElement, GeckoNode}; use style::gecko_bindings::bindings; use style::gecko_bindings::bindings::nsACString; use style::gecko_bindings::bindings::nsAString; @@ -163,16 +162,17 @@ use style::gecko_bindings::structs::Shee use style::gecko_bindings::structs::StyleContentType; use style::gecko_bindings::structs::StyleRuleInclusion; use style::gecko_bindings::structs::StyleSheet as DomStyleSheet; use style::gecko_bindings::structs::URLExtraData; use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasArcFFI, HasFFI}; use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong}; use style::gecko_bindings::sugar::refptr::RefPtr; use style::gecko_properties; +use style::global_style_data::{GlobalStyleData, GLOBAL_STYLE_DATA, STYLE_THREAD_POOL}; use style::invalidation::element::restyle_hints; use style::media_queries::MediaList; use style::parser::{self, Parse, ParserContext}; use style::properties::animated_properties::AnimationValue; use style::properties::{parse_one_declaration_into, parse_style_attribute}; use style::properties::{ComputedValues, Importance, NonCustomPropertyId}; use style::properties::{LonghandId, LonghandIdSet, PropertyDeclarationBlock, PropertyId}; use style::properties::{PropertyDeclarationId, ShorthandId};
--- a/servo/ports/geckolib/stylesheet_loader.rs +++ b/servo/ports/geckolib/stylesheet_loader.rs @@ -2,17 +2,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use cssparser::SourceLocation; use nsstring::nsCString; use servo_arc::Arc; use style::context::QuirksMode; use style::gecko::data::GeckoStyleSheet; -use style::gecko::global_style_data::GLOBAL_STYLE_DATA; +use style::global_style_data::GLOBAL_STYLE_DATA; use style::gecko_bindings::bindings; use style::gecko_bindings::bindings::Gecko_LoadStyleSheet; use style::gecko_bindings::structs::{Loader, LoaderReusableStyleSheets}; use style::gecko_bindings::structs::{ SheetLoadData, SheetLoadDataHolder, StyleSheet as DomStyleSheet, }; use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasBoxFFI, OwnedOrNull}; use style::gecko_bindings::sugar::refptr::RefPtr;
--- a/third_party/rust/lock_api/.cargo-checksum.json +++ b/third_party/rust/lock_api/.cargo-checksum.json @@ -1,1 +1,1 @@ -{"files":{"Cargo.toml":"9a369b3ff1ef121205879d10ba966bbccb81d6461843a75460f4cfcb82c3c849","src/lib.rs":"62142edfbe7e6cc04473aef25ab42553f02e4455ce567cb4303f0bbfee94d87d","src/mutex.rs":"d7ea4e06ae1a2d470e23bdfe73f52272f7c8b4231fe62fd9846e2a3773dcface","src/remutex.rs":"2fc11fec14af2886e507104e501caf6fddcf199ee7db38eabcd35ab9cf430d89","src/rwlock.rs":"45b940a9d046c7ee0c295237abac45f694c32a247724d93e3879a79f6e60b399"},"package":"949826a5ccf18c1b3a7c3d57692778d21768b79e46eb9dd07bfc4c2160036c54"} \ No newline at end of file +{"files":{"Cargo.toml":"ab2a7a96105e15de46900fb0da37edbab44e5513a9818672153dae44ed318f7e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","src/lib.rs":"4a16128f58e3380b22b26b137ee1096732995b7e401f3d227dd7b0738b6bd604","src/mutex.rs":"fee397f72325621812c5f78c7a6b9369ea7ec14e71bb0049678a50349519c0c7","src/remutex.rs":"ed76d7b93a56b6248d79676de2aaa66b607b64f1b773c9dd7326b8324e2bc71a","src/rwlock.rs":"5ab1aab614358cfdaf23e8ff8a0ac5e0c7656b777f385aca2e5422f0aa8f0985"},"package":"62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"} \ No newline at end of file
--- a/third_party/rust/lock_api/Cargo.toml +++ b/third_party/rust/lock_api/Cargo.toml @@ -7,25 +7,25 @@ # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] name = "lock_api" -version = "0.1.3" +version = "0.1.5" authors = ["Amanieu d'Antras <amanieu@gmail.com>"] description = "Wrappers to create fully-featured Mutex and RwLock types. Compatible with no_std." keywords = ["mutex", "rwlock", "lock", "no_std"] categories = ["concurrency", "no-std"] license = "Apache-2.0/MIT" repository = "https://github.com/Amanieu/parking_lot" [dependencies.owning_ref] -version = "0.3" +version = "0.4" optional = true [dependencies.scopeguard] version = "0.3" default-features = false [features] nightly = []
new file mode 100644 --- /dev/null +++ b/third_party/rust/lock_api/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License.
new file mode 100644 --- /dev/null +++ b/third_party/rust/lock_api/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2016 The Rust Project Developers + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE.
--- a/third_party/rust/lock_api/src/lib.rs +++ b/third_party/rust/lock_api/src/lib.rs @@ -6,42 +6,45 @@ // copied, modified, or distributed except according to those terms. //! This library provides type-safe and fully-featured `Mutex` and `RwLock` //! types which wrap a simple raw mutex or rwlock type. This has several //! benefits: not only does it eliminate a large portion of the work in //! implementing custom lock types, it also allows users to write code which is //! generic with regards to different lock implementations. //! -//! Basic usage of this crate is very straightfoward: +//! Basic usage of this crate is very straightforward: //! //! 1. Create a raw lock type. This should only contain the lock state, not any //! data protected by the lock. //! 2. Implement the `RawMutex` trait for your custom lock type. //! 3. Export your mutex as a type alias for `lock_api::Mutex`, and //! your mutex guard as a type alias for `lock_api::MutexGuard`. //! See the [example](#example) below for details. //! //! This process is similar for RwLocks, except that two guards need to be //! exported instead of one. (Or 3 guards if your type supports upgradable read //! locks, see [extension traits](#extension-traits) below for details) //! //! # Example //! //! ``` -//! use lock_api::{RawMutex, Mutex}; +//! use lock_api::{RawMutex, Mutex, GuardSend}; //! use std::sync::atomic::{AtomicBool, Ordering, ATOMIC_BOOL_INIT}; //! //! // 1. Define our raw lock type //! pub struct RawSpinlock(AtomicBool); //! //! // 2. Implement RawMutex for this type //! unsafe impl RawMutex for RawSpinlock { //! const INIT: RawSpinlock = RawSpinlock(ATOMIC_BOOL_INIT); //! +//! // A spinlock guard can be sent to another thread and unlocked there +//! type GuardMarker = GuardSend; +//! //! fn lock(&self) { //! // Note: This isn't the best way of implementing a spinlock, but it //! // suffices for the sake of this example. //! while !self.try_lock() {} //! } //! //! fn try_lock(&self) -> bool { //! self.0.swap(true, Ordering::Acquire)
--- a/third_party/rust/lock_api/src/mutex.rs +++ b/third_party/rust/lock_api/src/mutex.rs @@ -313,16 +313,43 @@ impl<'a, R: RawMutex + 'a, T: ?Sized + ' mem::forget(s); MappedMutexGuard { raw, data, marker: PhantomData, } } + /// Attempts to make a new `MappedMutexGuard` for a component of the + /// locked data. The original guard is return if the closure returns `None`. + /// + /// This operation cannot fail as the `MutexGuard` passed + /// in already locked the mutex. + /// + /// This is an associated function that needs to be + /// used as `MutexGuard::map(...)`. A method would interfere with methods of + /// the same name on the contents of the locked data. + #[inline] + pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> + where + F: FnOnce(&mut T) -> Option<&mut U>, + { + let raw = &s.mutex.raw; + let data = match f(unsafe { &mut *s.mutex.data.get() }) { + Some(data) => data, + None => return Err(s), + }; + mem::forget(s); + Ok(MappedMutexGuard { + raw, + data, + marker: PhantomData, + }) + } + /// Temporarily unlocks the mutex to execute the given function. /// /// This is safe because `&mut` guarantees that there exist no other /// references to the data protected by the mutex. #[inline] pub fn unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U, @@ -423,36 +450,63 @@ unsafe impl<'a, R: RawMutex + Sync + 'a, {} unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Send for MappedMutexGuard<'a, R, T> where R::GuardMarker: Send {} impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { /// Makes a new `MappedMutexGuard` for a component of the locked data. /// - /// This operation cannot fail as the `MutexGuard` passed + /// This operation cannot fail as the `MappedMutexGuard` passed /// in already locked the mutex. /// /// This is an associated function that needs to be - /// used as `MutexGuard::map(...)`. A method would interfere with methods of + /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U, { let raw = s.raw; let data = f(unsafe { &mut *s.data }); mem::forget(s); MappedMutexGuard { raw, data, marker: PhantomData, } } + + /// Attempts to make a new `MappedMutexGuard` for a component of the + /// locked data. The original guard is return if the closure returns `None`. + /// + /// This operation cannot fail as the `MappedMutexGuard` passed + /// in already locked the mutex. + /// + /// This is an associated function that needs to be + /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of + /// the same name on the contents of the locked data. + #[inline] + pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self> + where + F: FnOnce(&mut T) -> Option<&mut U>, + { + let raw = s.raw; + let data = match f(unsafe { &mut *s.data }) { + Some(data) => data, + None => return Err(s), + }; + mem::forget(s); + Ok(MappedMutexGuard { + raw, + data, + marker: PhantomData, + }) + } } impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> { /// Unlocks the mutex using a fair unlock protocol. /// /// By default, mutexes are unfair and allow the current thread to re-lock /// the mutex before another has the chance to acquire the lock, even if /// that thread has been blocked on the mutex for a long time. This is the
--- a/third_party/rust/lock_api/src/remutex.rs +++ b/third_party/rust/lock_api/src/remutex.rs @@ -263,17 +263,17 @@ impl<R: RawMutex, G: GetThreadId, T: ?Si /// still holding a reference to a `ReentrantMutexGuard`. #[inline] pub unsafe fn raw(&self) -> &R { &self.raw.mutex } } impl<R: RawMutexFair, G: GetThreadId, T: ?Sized> ReentrantMutex<R, G, T> { - /// Forcibly unlocks the mutex using a fair unlock procotol. + /// Forcibly unlocks the mutex using a fair unlock protocol. /// /// This is useful when combined with `mem::forget` to hold a lock without /// the need to maintain a `ReentrantMutexGuard` object alive, for example when /// dealing with FFI. /// /// # Safety /// /// This method must only be called if the current thread logically owns a @@ -380,16 +380,43 @@ impl<'a, R: RawMutex + 'a, G: GetThreadI mem::forget(s); MappedReentrantMutexGuard { raw, data, marker: PhantomData, } } + /// Attempts to make a new `MappedReentrantMutexGuard` for a component of the + /// locked data. The original guard is return if the closure returns `None`. + /// + /// This operation cannot fail as the `ReentrantMutexGuard` passed + /// in already locked the mutex. + /// + /// This is an associated function that needs to be + /// used as `ReentrantMutexGuard::map(...)`. A method would interfere with methods of + /// the same name on the contents of the locked data. + #[inline] + pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedReentrantMutexGuard<'a, R, G, U>, Self> + where + F: FnOnce(&mut T) -> Option<&mut U>, + { + let raw = &s.remutex.raw; + let data = match f(unsafe { &mut *s.remutex.data.get() }) { + Some(data) => data, + None => return Err(s), + }; + mem::forget(s); + Ok(MappedReentrantMutexGuard { + raw, + data, + marker: PhantomData, + }) + } + /// Temporarily unlocks the mutex to execute the given function. /// /// This is safe because `&mut` guarantees that there exist no other /// references to the data protected by the mutex. #[inline] pub fn unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U, @@ -490,36 +517,63 @@ unsafe impl<'a, R: RawMutex + Sync + 'a, for MappedReentrantMutexGuard<'a, R, G, T> {} impl<'a, R: RawMutex + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> MappedReentrantMutexGuard<'a, R, G, T> { /// Makes a new `MappedReentrantMutexGuard` for a component of the locked data. /// - /// This operation cannot fail as the `ReentrantMutexGuard` passed + /// This operation cannot fail as the `MappedReentrantMutexGuard` passed /// in already locked the mutex. /// /// This is an associated function that needs to be - /// used as `ReentrantMutexGuard::map(...)`. A method would interfere with methods of + /// used as `MappedReentrantMutexGuard::map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedReentrantMutexGuard<'a, R, G, U> where F: FnOnce(&T) -> &U, { let raw = s.raw; let data = f(unsafe { &*s.data }); mem::forget(s); MappedReentrantMutexGuard { raw, data, marker: PhantomData, } } + + /// Attempts to make a new `MappedReentrantMutexGuard` for a component of the + /// locked data. The original guard is return if the closure returns `None`. + /// + /// This operation cannot fail as the `MappedReentrantMutexGuard` passed + /// in already locked the mutex. + /// + /// This is an associated function that needs to be + /// used as `MappedReentrantMutexGuard::map(...)`. A method would interfere with methods of + /// the same name on the contents of the locked data. + #[inline] + pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedReentrantMutexGuard<'a, R, G, U>, Self> + where + F: FnOnce(&T) -> Option<&U>, + { + let raw = s.raw; + let data = match f(unsafe { &*s.data }) { + Some(data) => data, + None => return Err(s), + }; + mem::forget(s); + Ok(MappedReentrantMutexGuard { + raw, + data, + marker: PhantomData, + }) + } } impl<'a, R: RawMutexFair + 'a, G: GetThreadId + 'a, T: ?Sized + 'a> MappedReentrantMutexGuard<'a, R, G, T> { /// Unlocks the mutex using a fair unlock protocol. /// /// By default, mutexes are unfair and allow the current thread to re-lock
--- a/third_party/rust/lock_api/src/rwlock.rs +++ b/third_party/rust/lock_api/src/rwlock.rs @@ -709,16 +709,43 @@ impl<'a, R: RawRwLock + 'a, T: ?Sized + mem::forget(s); MappedRwLockReadGuard { raw, data, marker: PhantomData, } } + /// Attempts to make a new `MappedRwLockReadGuard` for a component of the + /// locked data. The original guard is return if the closure returns `None`. + /// + /// This operation cannot fail as the `RwLockReadGuard` passed + /// in already locked the data. + /// + /// This is an associated function that needs to be + /// used as `RwLockReadGuard::map(...)`. A method would interfere with methods of + /// the same name on the contents of the locked data. + #[inline] + pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockReadGuard<'a, R, U>, Self> + where + F: FnOnce(&T) -> Option<&U>, + { + let raw = &s.rwlock.raw; + let data = match f(unsafe { &*s.rwlock.data.get() }) { + Some(data) => data, + None => return Err(s), + }; + mem::forget(s); + Ok(MappedRwLockReadGuard { + raw, + data, + marker: PhantomData, + }) + } + /// Temporarily unlocks the `RwLock` to execute the given function. /// /// The `RwLock` is unlocked a fair unlock protocol. /// /// This is safe because `&mut` guarantees that there exist no other /// references to the data protected by the `RwLock`. #[inline] pub fn unlocked<F, U>(s: &mut Self, f: F) -> U @@ -815,30 +842,57 @@ impl<'a, R: RawRwLock + 'a, T: ?Sized + /// /// This operation cannot fail as the `RwLockWriteGuard` passed /// in already locked the data. /// /// This is an associated function that needs to be /// used as `RwLockWriteGuard::map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] - pub fn map<U: ?Sized, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> + pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U, { - let raw = &orig.rwlock.raw; - let data = f(unsafe { &mut *orig.rwlock.data.get() }); - mem::forget(orig); + let raw = &s.rwlock.raw; + let data = f(unsafe { &mut *s.rwlock.data.get() }); + mem::forget(s); MappedRwLockWriteGuard { raw, data, marker: PhantomData, } } + /// Attempts to make a new `MappedRwLockWriteGuard` for a component of the + /// locked data. The original guard is return if the closure returns `None`. + /// + /// This operation cannot fail as the `RwLockWriteGuard` passed + /// in already locked the data. + /// + /// This is an associated function that needs to be + /// used as `RwLockWriteGuard::map(...)`. A method would interfere with methods of + /// the same name on the contents of the locked data. + #[inline] + pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, R, U>, Self> + where + F: FnOnce(&mut T) -> Option<&mut U>, + { + let raw = &s.rwlock.raw; + let data = match f(unsafe { &mut *s.rwlock.data.get() }) { + Some(data) => data, + None => return Err(s), + }; + mem::forget(s); + Ok(MappedRwLockWriteGuard { + raw, + data, + marker: PhantomData, + }) + } + /// Temporarily unlocks the `RwLock` to execute the given function. /// /// This is safe because `&mut` guarantees that there exist no other /// references to the data protected by the `RwLock`. #[inline] pub fn unlocked<F, U>(s: &mut Self, f: F) -> U where F: FnOnce() -> U, @@ -984,17 +1038,17 @@ impl<'a, R: RawRwLockUpgrade + 'a, T: ?S F: FnOnce() -> U, { s.rwlock.raw.unlock_upgradable(); defer!(s.rwlock.raw.lock_upgradable()); f() } /// Atomically upgrades an upgradable read lock lock into a exclusive write lock, - /// blocking the current thread until it can be aquired. + /// blocking the current thread until it can be acquired. pub fn upgrade(s: Self) -> RwLockWriteGuard<'a, R, T> { s.rwlock.raw.upgrade(); let rwlock = s.rwlock; mem::forget(s); RwLockWriteGuard { rwlock, marker: PhantomData, } @@ -1184,16 +1238,43 @@ impl<'a, R: RawRwLock + 'a, T: ?Sized + let data = f(unsafe { &*s.data }); mem::forget(s); MappedRwLockReadGuard { raw, data, marker: PhantomData, } } + + /// Attempts to make a new `MappedRwLockReadGuard` for a component of the + /// locked data. The original guard is return if the closure returns `None`. + /// + /// This operation cannot fail as the `MappedRwLockReadGuard` passed + /// in already locked the data. + /// + /// This is an associated function that needs to be + /// used as `MappedRwLockReadGuard::map(...)`. A method would interfere with methods of + /// the same name on the contents of the locked data. + #[inline] + pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockReadGuard<'a, R, U>, Self> + where + F: FnOnce(&T) -> Option<&U>, + { + let raw = s.raw; + let data = match f(unsafe { &*s.data }) { + Some(data) => data, + None => return Err(s), + }; + mem::forget(s); + Ok(MappedRwLockReadGuard { + raw, + data, + marker: PhantomData, + }) + } } impl<'a, R: RawRwLockFair + 'a, T: ?Sized + 'a> MappedRwLockReadGuard<'a, R, T> { /// Unlocks the `RwLock` using a fair unlock protocol. /// /// By default, `RwLock` is unfair and allow the current thread to re-lock /// the `RwLock` before another has the chance to acquire the lock, even if /// that thread has been blocked on the `RwLock` for a long time. This is @@ -1257,29 +1338,56 @@ impl<'a, R: RawRwLock + 'a, T: ?Sized + /// /// This operation cannot fail as the `MappedRwLockWriteGuard` passed /// in already locked the data. /// /// This is an associated function that needs to be /// used as `MappedRwLockWriteGuard::map(...)`. A method would interfere with methods of /// the same name on the contents of the locked data. #[inline] - pub fn map<U: ?Sized, F>(orig: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> + pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedRwLockWriteGuard<'a, R, U> where F: FnOnce(&mut T) -> &mut U, { - let raw = orig.raw; - let data = f(unsafe { &mut *orig.data }); - mem::forget(orig); + let raw = s.raw; + let data = f(unsafe { &mut *s.data }); + mem::forget(s); MappedRwLockWriteGuard { raw, data, marker: PhantomData, } } + + /// Attempts to make a new `MappedRwLockWriteGuard` for a component of the + /// locked data. The original guard is return if the closure returns `None`. + /// + /// This operation cannot fail as the `MappedRwLockWriteGuard` passed + /// in already locked the data. + /// + /// This is an associated function that needs to be + /// used as `MappedRwLockWriteGuard::map(...)`. A method would interfere with methods of + /// the same name on the contents of the locked data. + #[inline] + pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, R, U>, Self> + where + F: FnOnce(&mut T) -> Option<&mut U>, + { + let raw = s.raw; + let data = match f(unsafe { &mut *s.data }) { + Some(data) => data, + None => return Err(s), + }; + mem::forget(s); + Ok(MappedRwLockWriteGuard { + raw, + data, + marker: PhantomData, + }) + } } impl<'a, R: RawRwLockDowngrade + 'a, T: ?Sized + 'a> MappedRwLockWriteGuard<'a, R, T> { /// Atomically downgrades a write lock into a read lock without allowing any /// writers to take exclusive access of the lock in the meantime. /// /// Note that if there are any writers currently waiting to take the lock /// then other readers may not be able to acquire the lock even if it was
--- a/third_party/rust/owning_ref/.cargo-checksum.json +++ b/third_party/rust/owning_ref/.cargo-checksum.json @@ -1,1 +1,1 @@ -{"files":{"Cargo.toml":"d6033830eecd6112eb61e775f848ab6c7ee76822ee1d7f8786b34e6e71f45b7b","LICENSE":"90bc15ed094593083fd129fdd1a03607be80fe8839c5564616a5961ab7f7a194","README.md":"e18ff10a148a8316e89bbe9f45cb57657170abe1a19154f8a5c968d529fe895e","src/lib.rs":"5d8857eee0de9863c3b6fce98732427cc1868a5ec3f0e3ce652ec011391aa842"},"package":"cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"} \ No newline at end of file +{"files":{"Cargo.toml":"9cc8936f2504375b24b88060b766a908e69690246cd063138b3a9b39287640d7","LICENSE":"90bc15ed094593083fd129fdd1a03607be80fe8839c5564616a5961ab7f7a194","README.md":"a479bb465878f3cbb8d53d2f42a26ac309e121d7c635956b7547a6bdfedce5d4","src/lib.rs":"e1e523638bea245fcf00b6643c61f856f2404f4d5d9ed0c230a6c4d2d8550b1c"},"package":"49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"} \ No newline at end of file
--- a/third_party/rust/owning_ref/Cargo.toml +++ b/third_party/rust/owning_ref/Cargo.toml @@ -1,15 +1,24 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g. crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + [package] name = "owning_ref" -version = "0.3.3" +version = "0.4.0" authors = ["Marvin Löbel <loebel.marvin@gmail.com>"] -license = "MIT" - description = "A library for creating references that carry their owner with them." -readme = "README.md" documentation = "http://kimundi.github.io/owning-ref-rs/owning_ref/index.html" - -repository = "https://github.com/Kimundi/owning-ref-rs" +readme = "README.md" keywords = ["reference", "sibling", "field", "owning"] - -[dependencies] -stable_deref_trait = "1.0.0" +license = "MIT" +repository = "https://github.com/Kimundi/owning-ref-rs" +[dependencies.stable_deref_trait] +version = "1.0.0"
--- a/third_party/rust/owning_ref/README.md +++ b/third_party/rust/owning_ref/README.md @@ -1,15 +1,15 @@ owning-ref-rs ============== A library for creating references that carry their owner with them. This can sometimes be useful because Rust borrowing rules normally prevent -moving a type that has been moved from. For example, this kind of code gets rejected: +moving a type that has been borrowed from. For example, this kind of code gets rejected: ```rust fn return_owned_and_referenced<'a>() -> (Vec<u8>, &'a [u8]) { let v = vec![1, 2, 3, 4]; let s = &v[1..3]; (v, s) } ```
--- a/third_party/rust/owning_ref/src/lib.rs +++ b/third_party/rust/owning_ref/src/lib.rs @@ -460,25 +460,23 @@ impl<O, T: ?Sized> OwningRef<O, T> { OwningRef { reference: self.reference, owner: self.owner.into_erased(), } } // TODO: wrap_owner - // FIXME: Naming convention? - /// A getter for the underlying owner. - pub fn owner(&self) -> &O { + /// A reference to the underlying owner. + pub fn as_owner(&self) -> &O { &self.owner } - // FIXME: Naming convention? /// Discards the reference and retrieves the owner. - pub fn into_inner(self) -> O { + pub fn into_owner(self) -> O { self.owner } } impl<O, T: ?Sized> OwningRefMut<O, T> { /// Creates a new owning reference from a owner /// initialized to the direct dereference of it. /// @@ -706,25 +704,28 @@ impl<O, T: ?Sized> OwningRefMut<O, T> { OwningRefMut { reference: self.reference, owner: self.owner.into_erased(), } } // TODO: wrap_owner - // FIXME: Naming convention? - /// A getter for the underlying owner. - pub fn owner(&self) -> &O { + /// A reference to the underlying owner. + pub fn as_owner(&self) -> &O { &self.owner } - // FIXME: Naming convention? + /// A mutable reference to the underlying owner. + pub fn as_owner_mut(&mut self) -> &mut O { + &mut self.owner + } + /// Discards the reference and retrieves the owner. - pub fn into_inner(self) -> O { + pub fn into_owner(self) -> O { self.owner } } ///////////////////////////////////////////////////////////////////////////// // OwningHandle ///////////////////////////////////////////////////////////////////////////// @@ -850,16 +851,26 @@ impl<O, H> OwningHandle<O, H> h = f(o.deref() as *const O::Target)?; } Ok(OwningHandle { handle: h, _owner: o, }) } + + /// A getter for the underlying owner. + pub fn as_owner(&self) -> &O { + &self._owner + } + + /// Discards the dependent object and returns the owner. + pub fn into_owner(self) -> O { + self._owner + } } ///////////////////////////////////////////////////////////////////////////// // std traits ///////////////////////////////////////////////////////////////////////////// use std::convert::From; use std::fmt::{self, Debug}; @@ -893,16 +904,18 @@ impl<O, T: ?Sized> DerefMut for OwningRe unsafe { &mut *self.reference } } } unsafe impl<O, T: ?Sized> StableAddress for OwningRef<O, T> {} +unsafe impl<O, T: ?Sized> StableAddress for OwningRefMut<O, T> {} + impl<O, T: ?Sized> AsRef<T> for OwningRef<O, T> { fn as_ref(&self) -> &T { &*self } } impl<O, T: ?Sized> AsRef<T> for OwningRefMut<O, T> { fn as_ref(&self) -> &T { @@ -947,38 +960,38 @@ impl<O, T: ?Sized> From<OwningRefMut<O, fn from(other: OwningRefMut<O, T>) -> Self { OwningRef { owner: other.owner, reference: other.reference, } } } -// ^ FIXME: Is a Into impl for calling into_inner() possible as well? +// ^ FIXME: Is a Into impl for calling into_owner() possible as well? impl<O, T: ?Sized> Debug for OwningRef<O, T> where O: Debug, T: Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "OwningRef {{ owner: {:?}, reference: {:?} }}", - self.owner(), + self.as_owner(), &**self) } } impl<O, T: ?Sized> Debug for OwningRefMut<O, T> where O: Debug, T: Debug, { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { write!(f, "OwningRefMut {{ owner: {:?}, reference: {:?} }}", - self.owner(), + self.as_owner(), &**self) } } impl<O, T: ?Sized> Clone for OwningRef<O, T> where O: CloneStableAddress, { fn clone(&self) -> Self { @@ -1114,17 +1127,17 @@ pub type VecRefMut<T, U = T> = OwningRef /// Typedef of a mutable owning reference that uses a `String` as the owner. pub type StringRefMut = OwningRefMut<String, str>; /// Typedef of a mutable owning reference that uses a `RefMut` as the owner. pub type RefMutRefMut<'a, T, U = T> = OwningRefMut<RefMut<'a, T>, U>; /// Typedef of a mutable owning reference that uses a `MutexGuard` as the owner. pub type MutexGuardRefMut<'a, T, U = T> = OwningRefMut<MutexGuard<'a, T>, U>; /// Typedef of a mutable owning reference that uses a `RwLockWriteGuard` as the owner. -pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRef<RwLockWriteGuard<'a, T>, U>; +pub type RwLockWriteGuardRefMut<'a, T, U = T> = OwningRefMut<RwLockWriteGuard<'a, T>, U>; unsafe impl<'a, T: 'a> IntoErased<'a> for Box<T> { type Erased = Box<Erased + 'a>; fn into_erased(self) -> Self::Erased { self } } unsafe impl<'a, T: 'a> IntoErased<'a> for Rc<T> { @@ -1216,29 +1229,29 @@ mod tests { fn map_chained_inference() { let or = BoxRef::new(Box::new(example().1)) .map(|x| &x[..5]) .map(|x| &x[1..3]); assert_eq!(&*or, "el"); } #[test] - fn owner() { + fn as_owner() { let or: BoxRef<String> = Box::new(example().1).into(); let or = or.map(|x| &x[..5]); assert_eq!(&*or, "hello"); - assert_eq!(&**or.owner(), "hello world"); + assert_eq!(&**or.as_owner(), "hello world"); } #[test] - fn into_inner() { + fn into_owner() { let or: BoxRef<String> = Box::new(example().1).into(); let or = or.map(|x| &x[..5]); assert_eq!(&*or, "hello"); - let s = *or.into_inner(); + let s = *or.into_owner(); assert_eq!(&s, "hello world"); } #[test] fn fmt_debug() { let or: BoxRef<String> = Box::new(example().1).into(); let or = or.map(|x| &x[..5]); let s = format!("{:?}", or); @@ -1257,18 +1270,25 @@ mod tests { assert!(os.iter().all(|e| &e[..] == "hello world")); } #[test] fn non_static_erased_owner() { let foo = [413, 612]; let bar = &foo; + // FIXME: lifetime inference fails us, and we can't easily define a lifetime for a closure + // (see https://github.com/rust-lang/rust/issues/22340) + // So we use a function to identify the lifetimes instead. + fn borrow<'a>(a: &'a &[i32; 2]) -> &'a i32 { + &a[0] + } + let o: BoxRef<&[i32; 2]> = Box::new(bar).into(); - let o: BoxRef<&[i32; 2], i32> = o.map(|a: &&[i32; 2]| &a[0]); + let o: BoxRef<&[i32; 2], i32> = o.map(borrow); let o: BoxRef<Erased, i32> = o.erase_owner(); assert_eq!(*o, 413); } #[test] fn raii_locks() { use super::super::{RefRef, RefMutRef}; @@ -1646,29 +1666,29 @@ mod tests { assert_eq!(&*or.unwrap(), "ello"); let or: BoxRefMut<String> = Box::new(example().1).into(); let or: Result<BoxRefMut<_, str>, ()> = or.try_map_mut(|_| Err(())); assert!(or.is_err()); } #[test] - fn owner() { + fn as_owner() { let or: BoxRefMut<String> = Box::new(example().1).into(); let or = or.map_mut(|x| &mut x[..5]); assert_eq!(&*or, "hello"); - assert_eq!(&**or.owner(), "hello world"); + assert_eq!(&**or.as_owner(), "hello world"); } #[test] - fn into_inner() { + fn into_owner() { let or: BoxRefMut<String> = Box::new(example().1).into(); let or = or.map_mut(|x| &mut x[..5]); assert_eq!(&*or, "hello"); - let s = *or.into_inner(); + let s = *or.into_owner(); assert_eq!(&s, "hello world"); } #[test] fn fmt_debug() { let or: BoxRefMut<String> = Box::new(example().1).into(); let or = or.map_mut(|x| &mut x[..5]); let s = format!("{:?}", or); @@ -1688,18 +1708,25 @@ mod tests { assert!(os.iter().all(|e| &e[..] == "hello world")); } #[test] fn non_static_erased_owner() { let mut foo = [413, 612]; let bar = &mut foo; + // FIXME: lifetime inference fails us, and we can't easily define a lifetime for a closure + // (see https://github.com/rust-lang/rust/issues/22340) + // So we use a function to identify the lifetimes instead. + fn borrow<'a>(a: &'a mut &mut [i32; 2]) -> &'a mut i32 { + &mut a[0] + } + let o: BoxRefMut<&mut [i32; 2]> = Box::new(bar).into(); - let o: BoxRefMut<&mut [i32; 2], i32> = o.map_mut(|a: &mut &mut [i32; 2]| &mut a[0]); + let o: BoxRefMut<&mut [i32; 2], i32> = o.map_mut(borrow); let o: BoxRefMut<Erased, i32> = o.erase_owner(); assert_eq!(*o, 413); } #[test] fn raii_locks() { use super::super::RefMutRefMut;