Auto merge of #118949 - matthiaskrgr:rollup-rdzlb9h, r=matthiaskrgr
Rollup of 4 pull requests Successful merges: - #118910 ([rustdoc] Use Map instead of Object for source files and search index) - #118914 (Unconditionally register alias-relate in projection goal) - #118935 (interpret: extend comment on the inhabitedness check in downcast) - #118945 (rustc_codegen_ssa: Remove trailing spaces in Display impl for CguReuse) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
de686cbc65
@ -199,8 +199,8 @@ impl fmt::Display for CguReuse {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match *self {
|
||||
CguReuse::No => write!(f, "No"),
|
||||
CguReuse::PreLto => write!(f, "PreLto "),
|
||||
CguReuse::PostLto => write!(f, "PostLto "),
|
||||
CguReuse::PreLto => write!(f, "PreLto"),
|
||||
CguReuse::PostLto => write!(f, "PostLto"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,6 +208,24 @@ where
|
||||
if layout.abi.is_uninhabited() {
|
||||
// `read_discriminant` should have excluded uninhabited variants... but ConstProp calls
|
||||
// us on dead code.
|
||||
// In the future we might want to allow this to permit code like this:
|
||||
// (this is a Rust/MIR pseudocode mix)
|
||||
// ```
|
||||
// enum Option2 {
|
||||
// Some(i32, !),
|
||||
// None,
|
||||
// }
|
||||
//
|
||||
// fn panic() -> ! { panic!() }
|
||||
//
|
||||
// let x: Option2;
|
||||
// x.Some.0 = 42;
|
||||
// x.Some.1 = panic();
|
||||
// SetDiscriminant(x, Some);
|
||||
// ```
|
||||
// However, for now we don't generate such MIR, and this check here *has* found real
|
||||
// bugs (see https://github.com/rust-lang/rust/issues/115145), so we will keep rejecting
|
||||
// it.
|
||||
throw_inval!(ConstPropNonsense)
|
||||
}
|
||||
// This cannot be `transmute` as variants *can* have a smaller size than the entire enum.
|
||||
|
@ -8,16 +8,28 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
&mut self,
|
||||
goal: Goal<'tcx, ProjectionPredicate<'tcx>>,
|
||||
) -> QueryResult<'tcx> {
|
||||
match goal.predicate.term.unpack() {
|
||||
ty::TermKind::Ty(term) => {
|
||||
let alias = goal.predicate.projection_ty.to_ty(self.tcx());
|
||||
self.eq(goal.param_env, alias, term)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
// FIXME(associated_const_equality): actually do something here.
|
||||
ty::TermKind::Const(_) => {
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
}
|
||||
let tcx = self.tcx();
|
||||
let projection_term = match goal.predicate.term.unpack() {
|
||||
ty::TermKind::Ty(_) => goal.predicate.projection_ty.to_ty(tcx).into(),
|
||||
ty::TermKind::Const(_) => ty::Const::new_unevaluated(
|
||||
tcx,
|
||||
ty::UnevaluatedConst::new(
|
||||
goal.predicate.projection_ty.def_id,
|
||||
goal.predicate.projection_ty.args,
|
||||
),
|
||||
tcx.type_of(goal.predicate.projection_ty.def_id)
|
||||
.instantiate(tcx, goal.predicate.projection_ty.args),
|
||||
)
|
||||
.into(),
|
||||
};
|
||||
self.add_goal(goal.with(
|
||||
tcx,
|
||||
ty::PredicateKind::AliasRelate(
|
||||
projection_term,
|
||||
goal.predicate.term,
|
||||
ty::AliasRelationDirection::Equate,
|
||||
),
|
||||
));
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
}
|
||||
}
|
||||
|
@ -488,7 +488,7 @@ pub(crate) fn build_index<'tcx>(
|
||||
|
||||
// Collect the index into a string
|
||||
format!(
|
||||
r#""{}":{}"#,
|
||||
r#"["{}",{}]"#,
|
||||
krate.name(tcx),
|
||||
serde_json::to_string(&CrateData {
|
||||
doc: crate_doc,
|
||||
|
@ -167,23 +167,24 @@ pub(super) fn write_shared(
|
||||
let mut krates = Vec::new();
|
||||
|
||||
if path.exists() {
|
||||
let prefix = format!("\"{krate}\"");
|
||||
let prefix = format!("[\"{krate}\"");
|
||||
for line in BufReader::new(File::open(path)?).lines() {
|
||||
let line = line?;
|
||||
if !line.starts_with('"') {
|
||||
if !line.starts_with("[\"") {
|
||||
continue;
|
||||
}
|
||||
if line.starts_with(&prefix) {
|
||||
continue;
|
||||
}
|
||||
if line.ends_with(",\\") {
|
||||
if line.ends_with("],\\") {
|
||||
ret.push(line[..line.len() - 2].to_string());
|
||||
} else {
|
||||
// Ends with "\\" (it's the case for the last added crate line)
|
||||
ret.push(line[..line.len() - 1].to_string());
|
||||
}
|
||||
krates.push(
|
||||
line.split('"')
|
||||
line[1..] // We skip the `[` parent at the beginning of the line.
|
||||
.split('"')
|
||||
.find(|s| !s.is_empty())
|
||||
.map(|s| s.to_owned())
|
||||
.unwrap_or_else(String::new),
|
||||
@ -285,7 +286,7 @@ pub(super) fn write_shared(
|
||||
let (mut all_sources, _krates) =
|
||||
try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst);
|
||||
all_sources.push(format!(
|
||||
r#""{}":{}"#,
|
||||
r#"["{}",{}]"#,
|
||||
&krate.name(cx.tcx()),
|
||||
hierarchy
|
||||
.to_json_string()
|
||||
@ -296,9 +297,9 @@ pub(super) fn write_shared(
|
||||
.replace("\\\"", "\\\\\"")
|
||||
));
|
||||
all_sources.sort();
|
||||
let mut v = String::from("var srcIndex = JSON.parse('{\\\n");
|
||||
let mut v = String::from("const srcIndex = new Map(JSON.parse('[\\\n");
|
||||
v.push_str(&all_sources.join(",\\\n"));
|
||||
v.push_str("\\\n}');\ncreateSrcSidebar();\n");
|
||||
v.push_str("\\\n]'));\ncreateSrcSidebar();\n");
|
||||
Ok(v.into_bytes())
|
||||
};
|
||||
write_invocation_specific("src-files.js", &make_sources)?;
|
||||
@ -316,11 +317,11 @@ pub(super) fn write_shared(
|
||||
// with rustdoc running in parallel.
|
||||
all_indexes.sort();
|
||||
write_invocation_specific("search-index.js", &|| {
|
||||
let mut v = String::from("var searchIndex = JSON.parse('{\\\n");
|
||||
let mut v = String::from("const searchIndex = new Map(JSON.parse('[\\\n");
|
||||
v.push_str(&all_indexes.join(",\\\n"));
|
||||
v.push_str(
|
||||
r#"\
|
||||
}');
|
||||
]'));
|
||||
if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)};
|
||||
if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
|
||||
"#,
|
||||
|
@ -80,10 +80,6 @@ const longItemTypes = [
|
||||
const TY_GENERIC = itemTypes.indexOf("generic");
|
||||
const ROOT_PATH = typeof window !== "undefined" ? window.rootPath : "../";
|
||||
|
||||
function hasOwnPropertyRustdoc(obj, property) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, property);
|
||||
}
|
||||
|
||||
// In the search display, allows to switch between tabs.
|
||||
function printTab(nb) {
|
||||
let iter = 0;
|
||||
@ -1074,7 +1070,7 @@ function initSearch(rawSearchIndex) {
|
||||
|
||||
if (elem &&
|
||||
elem.value !== "all crates" &&
|
||||
hasOwnPropertyRustdoc(rawSearchIndex, elem.value)
|
||||
rawSearchIndex.has(elem.value)
|
||||
) {
|
||||
return elem.value;
|
||||
}
|
||||
@ -2524,11 +2520,10 @@ ${item.displayPath}<span class="${type}">${name}</span>\
|
||||
}
|
||||
|
||||
let crates = "";
|
||||
const crates_list = Object.keys(rawSearchIndex);
|
||||
if (crates_list.length > 1) {
|
||||
if (rawSearchIndex.size > 1) {
|
||||
crates = " in <div id=\"crate-search-div\"><select id=\"crate-search\">" +
|
||||
"<option value=\"all crates\">all crates</option>";
|
||||
for (const c of crates_list) {
|
||||
for (const c of rawSearchIndex.keys()) {
|
||||
crates += `<option value="${c}" ${c === filterCrates && "selected"}>${c}</option>`;
|
||||
}
|
||||
crates += "</select></div>";
|
||||
@ -2945,81 +2940,70 @@ ${item.displayPath}<span class="${type}">${name}</span>\
|
||||
// Function type fingerprints are 128-bit bloom filters that are used to
|
||||
// estimate the distance between function and query.
|
||||
// This loop counts the number of items to allocate a fingerprint for.
|
||||
for (const crate in rawSearchIndex) {
|
||||
if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) {
|
||||
continue;
|
||||
}
|
||||
for (const crate of rawSearchIndex.values()) {
|
||||
// Each item gets an entry in the fingerprint array, and the crate
|
||||
// does, too
|
||||
id += rawSearchIndex[crate].t.length + 1;
|
||||
id += crate.t.length + 1;
|
||||
}
|
||||
functionTypeFingerprint = new Uint32Array((id + 1) * 4);
|
||||
|
||||
// This loop actually generates the search item indexes, including
|
||||
// normalized names, type signature objects and fingerprints, and aliases.
|
||||
id = 0;
|
||||
for (const crate in rawSearchIndex) {
|
||||
if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let crateSize = 0;
|
||||
|
||||
/**
|
||||
* The raw search data for a given crate. `n`, `t`, `d`, `i`, and `f`
|
||||
* are arrays with the same length. `q`, `a`, and `c` use a sparse
|
||||
* representation for compactness.
|
||||
*
|
||||
* `n[i]` contains the name of an item.
|
||||
*
|
||||
* `t[i]` contains the type of that item
|
||||
* (as a string of characters that represent an offset in `itemTypes`).
|
||||
*
|
||||
* `d[i]` contains the description of that item.
|
||||
*
|
||||
* `q` contains the full paths of the items. For compactness, it is a set of
|
||||
* (index, path) pairs used to create a map. If a given index `i` is
|
||||
* not present, this indicates "same as the last index present".
|
||||
*
|
||||
* `i[i]` contains an item's parent, usually a module. For compactness,
|
||||
* it is a set of indexes into the `p` array.
|
||||
*
|
||||
* `f[i]` contains function signatures, or `0` if the item isn't a function.
|
||||
* Functions are themselves encoded as arrays. The first item is a list of
|
||||
* types representing the function's inputs, and the second list item is a list
|
||||
* of types representing the function's output. Tuples are flattened.
|
||||
* Types are also represented as arrays; the first item is an index into the `p`
|
||||
* array, while the second is a list of types representing any generic parameters.
|
||||
*
|
||||
* b[i] contains an item's impl disambiguator. This is only present if an item
|
||||
* is defined in an impl block and, the impl block's type has more than one associated
|
||||
* item with the same name.
|
||||
*
|
||||
* `a` defines aliases with an Array of pairs: [name, offset], where `offset`
|
||||
* points into the n/t/d/q/i/f arrays.
|
||||
*
|
||||
* `doc` contains the description of the crate.
|
||||
*
|
||||
* `p` is a list of path/type pairs. It is used for parents and function parameters.
|
||||
*
|
||||
* `c` is an array of item indices that are deprecated.
|
||||
*
|
||||
* @type {{
|
||||
* doc: string,
|
||||
* a: Object,
|
||||
* n: Array<string>,
|
||||
* t: String,
|
||||
* d: Array<string>,
|
||||
* q: Array<[Number, string]>,
|
||||
* i: Array<Number>,
|
||||
* f: Array<RawFunctionSearchType>,
|
||||
* p: Array<Object>,
|
||||
* b: Array<[Number, String]>,
|
||||
* c: Array<Number>
|
||||
* }}
|
||||
*/
|
||||
const crateCorpus = rawSearchIndex[crate];
|
||||
|
||||
/**
|
||||
* The raw search data for a given crate. `n`, `t`, `d`, `i`, and `f`
|
||||
* are arrays with the same length. `q`, `a`, and `c` use a sparse
|
||||
* representation for compactness.
|
||||
*
|
||||
* `n[i]` contains the name of an item.
|
||||
*
|
||||
* `t[i]` contains the type of that item
|
||||
* (as a string of characters that represent an offset in `itemTypes`).
|
||||
*
|
||||
* `d[i]` contains the description of that item.
|
||||
*
|
||||
* `q` contains the full paths of the items. For compactness, it is a set of
|
||||
* (index, path) pairs used to create a map. If a given index `i` is
|
||||
* not present, this indicates "same as the last index present".
|
||||
*
|
||||
* `i[i]` contains an item's parent, usually a module. For compactness,
|
||||
* it is a set of indexes into the `p` array.
|
||||
*
|
||||
* `f[i]` contains function signatures, or `0` if the item isn't a function.
|
||||
* Functions are themselves encoded as arrays. The first item is a list of
|
||||
* types representing the function's inputs, and the second list item is a list
|
||||
* of types representing the function's output. Tuples are flattened.
|
||||
* Types are also represented as arrays; the first item is an index into the `p`
|
||||
* array, while the second is a list of types representing any generic parameters.
|
||||
*
|
||||
* b[i] contains an item's impl disambiguator. This is only present if an item
|
||||
* is defined in an impl block and, the impl block's type has more than one associated
|
||||
* item with the same name.
|
||||
*
|
||||
* `a` defines aliases with an Array of pairs: [name, offset], where `offset`
|
||||
* points into the n/t/d/q/i/f arrays.
|
||||
*
|
||||
* `doc` contains the description of the crate.
|
||||
*
|
||||
* `p` is a list of path/type pairs. It is used for parents and function parameters.
|
||||
*
|
||||
* `c` is an array of item indices that are deprecated.
|
||||
*
|
||||
* @type {{
|
||||
* doc: string,
|
||||
* a: Object,
|
||||
* n: Array<string>,
|
||||
* t: String,
|
||||
* d: Array<string>,
|
||||
* q: Array<[Number, string]>,
|
||||
* i: Array<Number>,
|
||||
* f: Array<RawFunctionSearchType>,
|
||||
* p: Array<Object>,
|
||||
* b: Array<[Number, String]>,
|
||||
* c: Array<Number>
|
||||
* }}
|
||||
*/
|
||||
for (const [crate, crateCorpus] of rawSearchIndex) {
|
||||
searchWords.push(crate);
|
||||
// This object should have exactly the same set of fields as the "row"
|
||||
// object defined below. Your JavaScript runtime will thank you.
|
||||
@ -3145,14 +3129,13 @@ ${item.displayPath}<span class="${type}">${name}</span>\
|
||||
id += 1;
|
||||
searchIndex.push(row);
|
||||
lastPath = row.path;
|
||||
crateSize += 1;
|
||||
}
|
||||
|
||||
if (aliases) {
|
||||
const currentCrateAliases = new Map();
|
||||
ALIASES.set(crate, currentCrateAliases);
|
||||
for (const alias_name in aliases) {
|
||||
if (!hasOwnPropertyRustdoc(aliases, alias_name)) {
|
||||
if (!Object.prototype.hasOwnProperty.call(aliases, alias_name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -3168,7 +3151,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
|
||||
}
|
||||
}
|
||||
}
|
||||
currentIndex += crateSize;
|
||||
currentIndex += itemTypes.length;
|
||||
}
|
||||
return searchWords;
|
||||
}
|
||||
@ -3377,7 +3360,7 @@ if (typeof window !== "undefined") {
|
||||
} else {
|
||||
// Running in Node, not a browser. Run initSearch just to produce the
|
||||
// exports.
|
||||
initSearch({});
|
||||
initSearch(new Map());
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,10 +118,10 @@ function createSrcSidebar() {
|
||||
title.className = "title";
|
||||
title.innerText = "Files";
|
||||
sidebar.appendChild(title);
|
||||
Object.keys(srcIndex).forEach(key => {
|
||||
srcIndex[key][NAME_OFFSET] = key;
|
||||
hasFoundFile = createDirEntry(srcIndex[key], sidebar, "", hasFoundFile);
|
||||
});
|
||||
for (const [key, source] of srcIndex) {
|
||||
source[NAME_OFFSET] = key;
|
||||
hasFoundFile = createDirEntry(source, sidebar, "", hasFoundFile);
|
||||
}
|
||||
|
||||
container.appendChild(sidebar);
|
||||
// Focus on the current file in the source files sidebar.
|
||||
|
21
tests/ui/traits/next-solver/closure-signature-inference-2.rs
Normal file
21
tests/ui/traits/next-solver/closure-signature-inference-2.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// compile-flags: -Znext-solver
|
||||
// check-pass
|
||||
|
||||
fn map<T: Default, U, F: FnOnce(T) -> U>(f: F) {
|
||||
f(T::default());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
map::<i32, _ /* ?U */, _ /* ?F */>(|x| x.to_string());
|
||||
// PREVIOUSLY when confirming the `map` call, we register:
|
||||
//
|
||||
// (1.) ?F: FnOnce<(i32,)>
|
||||
// (2.) <?F as FnOnce<(i32,)>>::Output projects-to ?U
|
||||
//
|
||||
// While (1.) is ambiguous, (2.) immediately gets processed
|
||||
// and we infer `?U := <?F as FnOnce<(i32,)>>::Output`.
|
||||
//
|
||||
// Thus, the only pending obligation that remains is (1.).
|
||||
// Since it is a trait obligation, we don't use it to deduce
|
||||
// the closure signature, and we fail!
|
||||
}
|
15
tests/ui/traits/next-solver/closure-signature-inference.rs
Normal file
15
tests/ui/traits/next-solver/closure-signature-inference.rs
Normal file
@ -0,0 +1,15 @@
|
||||
// compile-flags: -Znext-solver
|
||||
// check-pass
|
||||
|
||||
struct A;
|
||||
impl A {
|
||||
fn hi(self) {}
|
||||
}
|
||||
|
||||
fn hello() -> Result<(A,), ()> {
|
||||
Err(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = hello().map(|(x,)| x.hi());
|
||||
}
|
@ -1,8 +1,18 @@
|
||||
error[E0284]: type annotations needed: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc normalizes-to <<Leaf as WithAssoc<_>>::Assoc as Id>::Assoc`
|
||||
error[E0284]: type annotations needed
|
||||
--> $DIR/generalize-proj-new-universe-index-2.rs:74:5
|
||||
|
|
||||
LL | bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc normalizes-to <<Leaf as WithAssoc<_>>::Assoc as Id>::Assoc`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound`
|
||||
|
|
||||
= note: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc == _`
|
||||
note: required by a bound in `bound`
|
||||
--> $DIR/generalize-proj-new-universe-index-2.rs:69:21
|
||||
|
|
||||
LL | fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
|
||||
| ----- required by a bound in this function
|
||||
LL | where
|
||||
LL | T: WithAssoc<U, Assoc = V>,
|
||||
| ^^^^^^^^^ required by this bound in `bound`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user