Skip to content

Commit

Permalink
Auto merge of rust-lang#101639 - matthiaskrgr:rollup-sewkrgm, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 6 pull requests

Successful merges:

 - rust-lang#101413 (Use RelocModel::Pic for UEFI targets)
 - rust-lang#101595 (Fix ICE report flags display.)
 - rust-lang#101616 (Adapt test for msan message change)
 - rust-lang#101624 (rustdoc: remove unused CSS `#search { position: relative }`)
 - rust-lang#101633 (Rustdoc-Json: Correcty handle intra-doc-links to items without HTML page)
 - rust-lang#101634 (Rustdoc-Json Tests: Use ``@is`` and ``@ismany`` more often.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Sep 10, 2022
2 parents cedd26b + 973059e commit db9d86b
Show file tree
Hide file tree
Showing 21 changed files with 138 additions and 78 deletions.
11 changes: 7 additions & 4 deletions compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,22 +1119,25 @@ fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
while let Some(arg) = args.next() {
if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) {
let content = if arg.len() == a.len() {
// A space-separated option, like `-C incremental=foo` or `--crate-type rlib`
match args.next() {
Some(arg) => arg.to_string(),
None => continue,
}
} else if arg.get(a.len()..a.len() + 1) == Some("=") {
// An equals option, like `--crate-type=rlib`
arg[a.len() + 1..].to_string()
} else {
// A non-space option, like `-Cincremental=foo`
arg[a.len()..].to_string()
};
if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| content.starts_with(exc)) {
let option = content.split_once('=').map(|s| s.0).unwrap_or(&content);
if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.iter().any(|exc| option == *exc) {
excluded_cargo_defaults = true;
} else {
result.push(a.to_string());
match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| content.starts_with(*s))
{
Some(s) => result.push(s.to_string()),
match ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.iter().find(|s| option == **s) {
Some(s) => result.push(format!("{}=[REDACTED]", s)),
None => result.push(content),
}
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/spec/tests/tests_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ impl Target {
if self.position_independent_executables && !triple.ends_with("-linuxkernel") {
assert_eq!(self.relocation_model, RelocModel::Pic);
}
if self.relocation_model == RelocModel::Pic {
// The UEFI targets do not support dynamic linking but still require PIC (#101377).
if self.relocation_model == RelocModel::Pic && self.os != "uefi" {
assert!(self.dynamic_linking || self.position_independent_executables);
}
if self.static_position_independent_executables {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_target/src/spec/uefi_msvc_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// code runs in the same environment, no process separation is supported.

use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy};
use crate::spec::{RelocModel, StackProbeType, TargetOptions};
use crate::spec::{StackProbeType, TargetOptions};

pub fn opts() -> TargetOptions {
let mut base = super::msvc_base::opts();
Expand Down Expand Up @@ -47,7 +47,6 @@ pub fn opts() -> TargetOptions {
stack_probes: StackProbeType::Call,
singlethread: true,
linker: Some("rust-lld".into()),
relocation_model: RelocModel::Static,
..base
}
}
7 changes: 5 additions & 2 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,7 @@ impl Item {
.get(&self.item_id)
.map_or(&[][..], |v| v.as_slice())
.iter()
.filter_map(|ItemLink { link: s, link_text, did, ref fragment }| {
.filter_map(|ItemLink { link: s, link_text, page_id: did, ref fragment }| {
debug!(?did);
if let Ok((mut href, ..)) = href(*did, cx) {
debug!(?href);
Expand Down Expand Up @@ -1134,7 +1134,10 @@ pub(crate) struct ItemLink {
/// This may not be the same as `link` if there was a disambiguator
/// in an intra-doc link (e.g. \[`fn@f`\])
pub(crate) link_text: String,
pub(crate) did: DefId,
/// The `DefId` of the Item whose **HTML Page** contains the item being
/// linked to. This will be different to `item_id` on item's that don't
/// have their own page, such as struct fields and enum variants.
pub(crate) page_id: DefId,
/// The url fragment to append to the link
pub(crate) fragment: Option<UrlFragment>,
}
Expand Down
5 changes: 0 additions & 5 deletions src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -592,10 +592,6 @@ h2.location a {
margin: 0;
}

#search {
position: relative;
}

.search-loading {
text-align: center;
}
Expand Down Expand Up @@ -973,7 +969,6 @@ so that we can apply CSS-filters to change the arrow color in themes */

.search-results > a {
display: block;
width: 100%;
/* A little margin ensures the browser's outlining of focused links has room to display. */
margin-left: 2px;
margin-right: 2px;
Expand Down
11 changes: 9 additions & 2 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::clean::utils::print_const_expr;
use crate::clean::{self, ItemId};
use crate::formats::item_type::ItemType;
use crate::json::JsonRenderer;
use crate::passes::collect_intra_doc_links::UrlFragment;

impl JsonRenderer<'_> {
pub(super) fn convert_item(&self, item: clean::Item) -> Option<Item> {
Expand All @@ -29,8 +30,14 @@ impl JsonRenderer<'_> {
.get(&item.item_id)
.into_iter()
.flatten()
.map(|clean::ItemLink { link, did, .. }| {
(link.clone(), from_item_id((*did).into(), self.tcx))
.map(|clean::ItemLink { link, page_id, fragment, .. }| {
let id = match fragment {
Some(UrlFragment::Item(frag_id)) => *frag_id,
// FIXME: Pass the `UserWritten` segment to JSON consumer.
Some(UrlFragment::UserWritten(_)) | None => *page_id,
};

(link.clone(), from_item_id(id.into(), self.tcx))
})
.collect();
let docs = item.attrs.collapsed_doc_value();
Expand Down
10 changes: 7 additions & 3 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,9 @@ enum MalformedGenerics {
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub(crate) enum UrlFragment {
Item(DefId),
/// A part of a page that isn't a rust item.
///
/// Eg: `[Vector Examples](std::vec::Vec#examples)`
UserWritten(String),
}

Expand Down Expand Up @@ -1127,7 +1130,7 @@ impl LinkCollector<'_, '_> {
Some(ItemLink {
link: ori_link.link.clone(),
link_text: link_text.clone(),
did: res.def_id(self.cx.tcx),
page_id: res.def_id(self.cx.tcx),
fragment,
})
}
Expand All @@ -1146,11 +1149,12 @@ impl LinkCollector<'_, '_> {
item,
&diag_info,
)?;
let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));

let page_id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));
Some(ItemLink {
link: ori_link.link.clone(),
link_text: link_text.clone(),
did: id,
page_id,
fragment,
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/codegen/abi-efiapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ trait Freeze { }
#[lang="copy"]
trait Copy { }

//x86_64: define dso_local win64cc void @has_efiapi
//x86_64: define win64cc void @has_efiapi
//i686: define void @has_efiapi
//aarch64: define dso_local void @has_efiapi
//arm: define dso_local void @has_efiapi
Expand Down
4 changes: 2 additions & 2 deletions src/test/rustdoc-gui/search-result-display.goml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ press-key: 'Enter'
wait-for: "#crate-search"
// The width is returned by "getComputedStyle" which returns the exact number instead of the
// CSS rule which is "50%"...
assert-css: (".search-results div.desc", {"width": "295px"})
assert-css: (".search-results div.desc", {"width": "293px"})
size: (600, 100)
// As counter-intuitive as it may seem, in this width, the width is "100%", which is why
// when computed it's larger.
assert-css: (".search-results div.desc", {"width": "570px"})
assert-css: (".search-results div.desc", {"width": "566px"})

// Check that the crate filter `<select>` is correctly handled when it goes to next line.
// To do so we need to update the length of one of its `<option>`.
Expand Down
30 changes: 20 additions & 10 deletions src/test/rustdoc-json/assoc_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,35 @@
pub struct Simple;

impl Simple {
// @has "$.index[*][?(@.name=='CONSTANT')].kind" \"assoc_const\"
// @is "$.index[*][?(@.name=='CONSTANT')].kind" \"assoc_const\"
pub const CONSTANT: usize = 0;
}

pub trait EasyToImpl {
// @has "$.index[*][?(@.name=='ToDeclare')].kind" \"assoc_type\"
// @has "$.index[*][?(@.name=='ToDeclare')].inner.default" null
// @is "$.index[*][?(@.docs=='ToDeclare trait')].kind" \"assoc_type\"
// @is "$.index[*][?(@.docs=='ToDeclare trait')].inner.default" null
// @is "$.index[*][?(@.docs=='ToDeclare trait')].inner.bounds" []
/// ToDeclare trait
type ToDeclare;
// @has "$.index[*][?(@.name=='AN_ATTRIBUTE')].kind" \"assoc_const\"
// @has "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.default" null
// @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].kind" \"assoc_const\"
// @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.default" null
// @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.type.kind" '"primitive"'
// @is "$.index[*][?(@.docs=='AN_ATTRIBUTE trait')].inner.type.inner" '"usize"'
/// AN_ATTRIBUTE trait
const AN_ATTRIBUTE: usize;
}

impl EasyToImpl for Simple {
// @has "$.index[*][?(@.name=='ToDeclare')].inner.default.kind" \"primitive\"
// @has "$.index[*][?(@.name=='ToDeclare')].inner.default.inner" \"usize\"
// @is "$.index[*][?(@.docs=='ToDeclare impl')].kind" '"assoc_type"'
// @is "$.index[*][?(@.docs=='ToDeclare impl')].inner.default.kind" \"primitive\"
// @is "$.index[*][?(@.docs=='ToDeclare impl')].inner.default.inner" \"usize\"
/// ToDeclare impl
type ToDeclare = usize;
// @has "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.type.kind" \"primitive\"
// @has "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.type.inner" \"usize\"
// @has "$.index[*][?(@.name=='AN_ATTRIBUTE')].inner.default" \"12\"

// @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].kind" '"assoc_const"'
// @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.type.kind" \"primitive\"
// @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.type.inner" \"usize\"
// @is "$.index[*][?(@.docs=='AN_ATTRIBUTE impl')].inner.default" \"12\"
/// AN_ATTRIBUTE impl
const AN_ATTRIBUTE: usize = 12;
}
10 changes: 5 additions & 5 deletions src/test/rustdoc-json/enums/variant_struct.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// @has "$.index[*][?(@.name=='EnumStruct')].visibility" \"public\"
// @has "$.index[*][?(@.name=='EnumStruct')].kind" \"enum\"
// @is "$.index[*][?(@.name=='EnumStruct')].visibility" \"public\"
// @is "$.index[*][?(@.name=='EnumStruct')].kind" \"enum\"
pub enum EnumStruct {
// @has "$.index[*][?(@.name=='VariantS')].inner.variant_kind" \"struct\"
// @has "$.index[*][?(@.name=='x')].kind" \"struct_field\"
// @has "$.index[*][?(@.name=='y')].kind" \"struct_field\"
// @is "$.index[*][?(@.name=='VariantS')].inner.variant_kind" \"struct\"
// @is "$.index[*][?(@.name=='x')].kind" \"struct_field\"
// @is "$.index[*][?(@.name=='y')].kind" \"struct_field\"
VariantS {
x: u32,
y: String,
Expand Down
10 changes: 5 additions & 5 deletions src/test/rustdoc-json/enums/variant_tuple_struct.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// @has "$.index[*][?(@.name=='EnumTupleStruct')].visibility" \"public\"
// @has "$.index[*][?(@.name=='EnumTupleStruct')].kind" \"enum\"
// @is "$.index[*][?(@.name=='EnumTupleStruct')].visibility" \"public\"
// @is "$.index[*][?(@.name=='EnumTupleStruct')].kind" \"enum\"
pub enum EnumTupleStruct {
// @has "$.index[*][?(@.name=='VariantA')].inner.variant_kind" \"tuple\"
// @has "$.index[*][?(@.name=='0')].kind" \"struct_field\"
// @has "$.index[*][?(@.name=='1')].kind" \"struct_field\"
// @is "$.index[*][?(@.name=='VariantA')].inner.variant_kind" \"tuple\"
// @is "$.index[*][?(@.name=='0')].kind" \"struct_field\"
// @is "$.index[*][?(@.name=='1')].kind" \"struct_field\"
VariantA(u32, String),
}
8 changes: 4 additions & 4 deletions src/test/rustdoc-json/fns/generics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ pub trait Wham {}
// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.where_predicates" []
// @count "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[*]" 1
// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].name" '"T"'
// @has "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
// @has "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" false
// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
// @is "$.index[*][?(@.name=='one_generic_param_fn')].inner.decl.inputs" '[["w", {"inner": "T", "kind": "generic"}]]'
pub fn one_generic_param_fn<T: Wham>(w: T) {}

// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.where_predicates" []
// @count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[*]" 1
// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].name" '"impl Wham"'
// @has "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
// @has "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.synthetic" true
// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.generics.params[0].kind.type.bounds[0].trait_bound.trait.id" $wham_id
// @count "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[*]" 1
// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][0]" '"w"'
// @is "$.index[*][?(@.name=='one_synthetic_generic_param_fn')].inner.decl.inputs[0][1].kind" '"impl_trait"'
Expand Down
10 changes: 4 additions & 6 deletions src/test/rustdoc-json/impls/import_from_private.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ mod bar {
// @set import = "$.index[*][?(@.kind=='import')].id"
pub use bar::Baz;

// FIXME(adotinthevoid): Use hasexact once #99474 lands

// @has "$.index[*][?(@.kind=='module')].inner.items[*]" $import
// @is "$.index[*][?(@.kind=='import')].inner.id" $baz
// @has "$.index[*][?(@.kind=='struct')].inner.impls[*]" $impl
// @has "$.index[*][?(@.kind=='impl')].inner.items[*]" $doit
// @is "$.index[*][?(@.kind=='module')].inner.items[*]" $import
// @is "$.index[*][?(@.kind=='import')].inner.id" $baz
// @is "$.index[*][?(@.kind=='struct')].inner.impls[*]" $impl
// @is "$.index[*][?(@.kind=='impl')].inner.items[*]" $doit
34 changes: 34 additions & 0 deletions src/test/rustdoc-json/intra-doc-links/non_page.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Regression test for <https://github.com/rust-lang/rust/issues/101531>,
// where links where to the item who's HTML page had the item linked to.

//! [`Struct::struct_field`]
//! [`Enum::Variant`]
//! [`Trait::AssocType`]
//! [`Trait::ASSOC_CONST`]
//! [`Trait::method`]
// @set struct_field = "$.index[*][?(@.name=='struct_field')].id"
// @set Variant = "$.index[*][?(@.name=='Variant')].id"
// @set AssocType = "$.index[*][?(@.name=='AssocType')].id"
// @set ASSOC_CONST = "$.index[*][?(@.name=='ASSOC_CONST')].id"
// @set method = "$.index[*][?(@.name=='method')].id"

// @is "$.index[*][?(@.name=='non_page')].links['`Struct::struct_field`']" $struct_field
// @is "$.index[*][?(@.name=='non_page')].links['`Enum::Variant`']" $Variant
// @is "$.index[*][?(@.name=='non_page')].links['`Trait::AssocType`']" $AssocType
// @is "$.index[*][?(@.name=='non_page')].links['`Trait::ASSOC_CONST`']" $ASSOC_CONST
// @is "$.index[*][?(@.name=='non_page')].links['`Trait::method`']" $method

pub struct Struct {
pub struct_field: i32,
}

pub enum Enum {
Variant(),
}

pub trait Trait {
const ASSOC_CONST: i32;
type AssocType;
fn method();
}
8 changes: 8 additions & 0 deletions src/test/rustdoc-json/intra-doc-links/user_written.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! For motivation, see [the reasons](foo#reasons)
/// # Reasons
/// To test rustdoc json
pub fn foo() {}

// @set foo = "$.index[*][?(@.name=='foo')].id"
// @is "$.index[*][?(@.name=='user_written')].links['foo#reasons']" $foo
22 changes: 11 additions & 11 deletions src/test/rustdoc-json/primitives.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
#![feature(never_type)]

// @has "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
// @has "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
// @has "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
// @is "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
// @is "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
// @is "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
pub type PrimNever = !;

// @has "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
// @has "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
// @is "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
// @is "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
pub type PrimStr = str;

// @has "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
// @has "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
// @is "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
// @is "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
pub type PrimBool = bool;

// @has "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
// @has "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
// @is "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
// @is "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
pub type PrimChar = char;

// @has "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
// @has "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
// @is "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
// @is "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
pub type PrimU8 = u8;
14 changes: 7 additions & 7 deletions src/test/rustdoc-json/traits/has_body.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
// @has "$.index[*][?(@.name=='Foo')]"
pub trait Foo {
// @has "$.index[*][?(@.name=='no_self')].inner.has_body" false
// @is "$.index[*][?(@.name=='no_self')].inner.has_body" false
fn no_self();
// @has "$.index[*][?(@.name=='move_self')].inner.has_body" false
// @is "$.index[*][?(@.name=='move_self')].inner.has_body" false
fn move_self(self);
// @has "$.index[*][?(@.name=='ref_self')].inner.has_body" false
// @is "$.index[*][?(@.name=='ref_self')].inner.has_body" false
fn ref_self(&self);

// @has "$.index[*][?(@.name=='no_self_def')].inner.has_body" true
// @is "$.index[*][?(@.name=='no_self_def')].inner.has_body" true
fn no_self_def() {}
// @has "$.index[*][?(@.name=='move_self_def')].inner.has_body" true
// @is "$.index[*][?(@.name=='move_self_def')].inner.has_body" true
fn move_self_def(self) {}
// @has "$.index[*][?(@.name=='ref_self_def')].inner.has_body" true
// @is "$.index[*][?(@.name=='ref_self_def')].inner.has_body" true
fn ref_self_def(&self) {}
}

pub trait Bar: Clone {
// @has "$.index[*][?(@.name=='method')].inner.has_body" false
// @is "$.index[*][?(@.name=='method')].inner.has_body" false
fn method(&self, param: usize);
}
Loading

0 comments on commit db9d86b

Please sign in to comment.