Auto merge of #124849 - matthiaskrgr:rollup-68humsk, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #124738 (rustdoc: dedup search form HTML) - #124827 (generalize hr alias: avoid unconstrainable infer vars) - #124832 (narrow down visibilities in `rustc_parse::lexer`) - #124842 (replace another Option<Span> by DUMMY_SP) - #124846 (Don't ICE when we cannot eval a const to a valtree in the new solver) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
b923ea4924
@ -7,7 +7,7 @@
|
|||||||
use rustc_middle::query::TyCtxtAt;
|
use rustc_middle::query::TyCtxtAt;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_middle::ty::{layout::LayoutError, ConstInt};
|
use rustc_middle::ty::{layout::LayoutError, ConstInt};
|
||||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
use super::CompileTimeInterpreter;
|
use super::CompileTimeInterpreter;
|
||||||
use crate::errors::{self, FrameNote, ReportErrorExt};
|
use crate::errors::{self, FrameNote, ReportErrorExt};
|
||||||
@ -121,7 +121,7 @@ pub fn get_span_and_frames<'tcx, 'mir>(
|
|||||||
pub(super) fn report<'tcx, C, F, E>(
|
pub(super) fn report<'tcx, C, F, E>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
error: InterpError<'tcx>,
|
error: InterpError<'tcx>,
|
||||||
span: Option<Span>,
|
span: Span,
|
||||||
get_span_and_frames: C,
|
get_span_and_frames: C,
|
||||||
mk: F,
|
mk: F,
|
||||||
) -> ErrorHandled
|
) -> ErrorHandled
|
||||||
@ -135,16 +135,16 @@ pub(super) fn report<'tcx, C, F, E>(
|
|||||||
// Don't emit a new diagnostic for these errors, they are already reported elsewhere or
|
// Don't emit a new diagnostic for these errors, they are already reported elsewhere or
|
||||||
// should remain silent.
|
// should remain silent.
|
||||||
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
|
err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => {
|
||||||
ErrorHandled::TooGeneric(span.unwrap_or(DUMMY_SP))
|
ErrorHandled::TooGeneric(span)
|
||||||
}
|
}
|
||||||
err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span.unwrap_or(DUMMY_SP)),
|
err_inval!(AlreadyReported(guar)) => ErrorHandled::Reported(guar, span),
|
||||||
err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
|
err_inval!(Layout(LayoutError::ReferencesError(guar))) => {
|
||||||
ErrorHandled::Reported(guar.into(), span.unwrap_or(DUMMY_SP))
|
ErrorHandled::Reported(guar.into(), span)
|
||||||
}
|
}
|
||||||
// Report remaining errors.
|
// Report remaining errors.
|
||||||
_ => {
|
_ => {
|
||||||
let (our_span, frames) = get_span_and_frames();
|
let (our_span, frames) = get_span_and_frames();
|
||||||
let span = span.unwrap_or(our_span);
|
let span = span.substitute_dummy(our_span);
|
||||||
let err = mk(span, frames);
|
let err = mk(span, frames);
|
||||||
let mut err = tcx.dcx().create_err(err);
|
let mut err = tcx.dcx().create_err(err);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_span::def_id::LocalDefId;
|
use rustc_span::def_id::LocalDefId;
|
||||||
use rustc_span::Span;
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
use rustc_target::abi::{self, Abi};
|
use rustc_target::abi::{self, Abi};
|
||||||
|
|
||||||
use super::{CanAccessMutGlobal, CompileTimeEvalContext, CompileTimeInterpreter};
|
use super::{CanAccessMutGlobal, CompileTimeEvalContext, CompileTimeInterpreter};
|
||||||
@ -298,7 +298,7 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
|
|||||||
super::report(
|
super::report(
|
||||||
tcx,
|
tcx,
|
||||||
error.into_kind(),
|
error.into_kind(),
|
||||||
Some(span),
|
span,
|
||||||
|| (span, vec![]),
|
|| (span, vec![]),
|
||||||
|span, _| errors::NullaryIntrinsicError { span },
|
|span, _| errors::NullaryIntrinsicError { span },
|
||||||
)
|
)
|
||||||
@ -406,7 +406,7 @@ fn eval_in_interpreter<'tcx, R: InterpretationResult<'tcx>>(
|
|||||||
super::report(
|
super::report(
|
||||||
*ecx.tcx,
|
*ecx.tcx,
|
||||||
error,
|
error,
|
||||||
None,
|
DUMMY_SP,
|
||||||
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
|
|| super::get_span_and_frames(ecx.tcx, ecx.stack()),
|
||||||
|span, frames| ConstEvalError { span, error_kind: kind, instance, frame_notes: frames },
|
|span, frames| ConstEvalError { span, error_kind: kind, instance, frame_notes: frames },
|
||||||
)
|
)
|
||||||
@ -461,7 +461,7 @@ fn report_validation_error<'mir, 'tcx>(
|
|||||||
crate::const_eval::report(
|
crate::const_eval::report(
|
||||||
*ecx.tcx,
|
*ecx.tcx,
|
||||||
error,
|
error,
|
||||||
None,
|
DUMMY_SP,
|
||||||
|| crate::const_eval::get_span_and_frames(ecx.tcx, ecx.stack()),
|
|| crate::const_eval::get_span_and_frames(ecx.tcx, ecx.stack()),
|
||||||
move |span, frames| errors::ValidationFailure { span, ub_note, frames, raw_bytes },
|
move |span, frames| errors::ValidationFailure { span, ub_note, frames, raw_bytes },
|
||||||
)
|
)
|
||||||
|
@ -31,6 +31,7 @@ struct ExpectedSig<'tcx> {
|
|||||||
sig: ty::PolyFnSig<'tcx>,
|
sig: ty::PolyFnSig<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct ClosureSignatures<'tcx> {
|
struct ClosureSignatures<'tcx> {
|
||||||
/// The signature users of the closure see.
|
/// The signature users of the closure see.
|
||||||
bound_sig: ty::PolyFnSig<'tcx>,
|
bound_sig: ty::PolyFnSig<'tcx>,
|
||||||
@ -713,25 +714,16 @@ fn merge_supplied_sig_with_expectation(
|
|||||||
// [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
|
// [c2]: https://github.com/rust-lang/rust/pull/45072#issuecomment-341096796
|
||||||
self.commit_if_ok(|_| {
|
self.commit_if_ok(|_| {
|
||||||
let mut all_obligations = vec![];
|
let mut all_obligations = vec![];
|
||||||
let inputs: Vec<_> = iter::zip(
|
let supplied_sig = self.instantiate_binder_with_fresh_vars(
|
||||||
decl.inputs,
|
self.tcx.def_span(expr_def_id),
|
||||||
supplied_sig.inputs().skip_binder(), // binder moved to (*) below
|
BoundRegionConversionTime::FnCall,
|
||||||
)
|
supplied_sig,
|
||||||
.map(|(hir_ty, &supplied_ty)| {
|
);
|
||||||
// Instantiate (this part of..) S to S', i.e., with fresh variables.
|
|
||||||
self.instantiate_binder_with_fresh_vars(
|
|
||||||
hir_ty.span,
|
|
||||||
BoundRegionConversionTime::FnCall,
|
|
||||||
// (*) binder moved to here
|
|
||||||
supplied_sig.inputs().rebind(supplied_ty),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// The liberated version of this signature should be a subtype
|
// The liberated version of this signature should be a subtype
|
||||||
// of the liberated form of the expectation.
|
// of the liberated form of the expectation.
|
||||||
for ((hir_ty, &supplied_ty), expected_ty) in iter::zip(
|
for ((hir_ty, &supplied_ty), expected_ty) in iter::zip(
|
||||||
iter::zip(decl.inputs, &inputs),
|
iter::zip(decl.inputs, supplied_sig.inputs()),
|
||||||
expected_sigs.liberated_sig.inputs(), // `liberated_sig` is E'.
|
expected_sigs.liberated_sig.inputs(), // `liberated_sig` is E'.
|
||||||
) {
|
) {
|
||||||
// Check that E' = S'.
|
// Check that E' = S'.
|
||||||
@ -744,11 +736,7 @@ fn merge_supplied_sig_with_expectation(
|
|||||||
all_obligations.extend(obligations);
|
all_obligations.extend(obligations);
|
||||||
}
|
}
|
||||||
|
|
||||||
let supplied_output_ty = self.instantiate_binder_with_fresh_vars(
|
let supplied_output_ty = supplied_sig.output();
|
||||||
decl.output.span(),
|
|
||||||
BoundRegionConversionTime::FnCall,
|
|
||||||
supplied_sig.output(),
|
|
||||||
);
|
|
||||||
let cause = &self.misc(decl.output.span());
|
let cause = &self.misc(decl.output.span());
|
||||||
let InferOk { value: (), obligations } = self.at(cause, self.param_env).eq(
|
let InferOk { value: (), obligations } = self.at(cause, self.param_env).eq(
|
||||||
DefineOpaqueTypes::Yes,
|
DefineOpaqueTypes::Yes,
|
||||||
@ -757,7 +745,8 @@ fn merge_supplied_sig_with_expectation(
|
|||||||
)?;
|
)?;
|
||||||
all_obligations.extend(obligations);
|
all_obligations.extend(obligations);
|
||||||
|
|
||||||
let inputs = inputs.into_iter().map(|ty| self.resolve_vars_if_possible(ty));
|
let inputs =
|
||||||
|
supplied_sig.inputs().into_iter().map(|&ty| self.resolve_vars_if_possible(ty));
|
||||||
|
|
||||||
expected_sigs.liberated_sig = self.tcx.mk_fn_sig(
|
expected_sigs.liberated_sig = self.tcx.mk_fn_sig(
|
||||||
inputs,
|
inputs,
|
||||||
@ -1013,6 +1002,7 @@ fn error_sig_of_closure(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "debug", skip(self), ret)]
|
||||||
fn closure_sigs(
|
fn closure_sigs(
|
||||||
&self,
|
&self,
|
||||||
expr_def_id: LocalDefId,
|
expr_def_id: LocalDefId,
|
||||||
|
@ -350,7 +350,13 @@ fn generalize_alias_ty(
|
|||||||
&mut self,
|
&mut self,
|
||||||
alias: ty::AliasTy<'tcx>,
|
alias: ty::AliasTy<'tcx>,
|
||||||
) -> Result<Ty<'tcx>, TypeError<'tcx>> {
|
) -> Result<Ty<'tcx>, TypeError<'tcx>> {
|
||||||
if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() {
|
// We do not eagerly replace aliases with inference variables if they have
|
||||||
|
// escaping bound vars, see the method comment for details. However, when we
|
||||||
|
// are inside of an alias with escaping bound vars replacing nested aliases
|
||||||
|
// with inference variables can cause incorrect ambiguity.
|
||||||
|
//
|
||||||
|
// cc trait-system-refactor-initiative#110
|
||||||
|
if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() && !self.in_alias {
|
||||||
return Ok(self.infcx.next_ty_var_in_universe(
|
return Ok(self.infcx.next_ty_var_in_universe(
|
||||||
TypeVariableOrigin { param_def_id: None, span: self.span },
|
TypeVariableOrigin { param_def_id: None, span: self.span },
|
||||||
self.for_universe,
|
self.for_universe,
|
||||||
@ -492,9 +498,30 @@ fn tys(&mut self, t: Ty<'tcx>, t2: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
|
|||||||
let origin = inner.type_variables().var_origin(vid);
|
let origin = inner.type_variables().var_origin(vid);
|
||||||
let new_var_id =
|
let new_var_id =
|
||||||
inner.type_variables().new_var(self.for_universe, origin);
|
inner.type_variables().new_var(self.for_universe, origin);
|
||||||
let u = Ty::new_var(self.tcx(), new_var_id);
|
// If we're in the new solver and create a new inference
|
||||||
debug!("replacing original vid={:?} with new={:?}", vid, u);
|
// variable inside of an alias we eagerly constrain that
|
||||||
Ok(u)
|
// inference variable to prevent unexpected ambiguity errors.
|
||||||
|
//
|
||||||
|
// This is incomplete as it pulls down the universe of the
|
||||||
|
// original inference variable, even though the alias could
|
||||||
|
// normalize to a type which does not refer to that type at
|
||||||
|
// all. I don't expect this to cause unexpected errors in
|
||||||
|
// practice.
|
||||||
|
//
|
||||||
|
// We only need to do so for type and const variables, as
|
||||||
|
// region variables do not impact normalization, and will get
|
||||||
|
// correctly constrained by `AliasRelate` later on.
|
||||||
|
//
|
||||||
|
// cc trait-system-refactor-initiative#108
|
||||||
|
if self.infcx.next_trait_solver()
|
||||||
|
&& !self.infcx.intercrate
|
||||||
|
&& self.in_alias
|
||||||
|
{
|
||||||
|
inner.type_variables().equate(vid, new_var_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!("replacing original vid={:?} with new={:?}", vid, new_var_id);
|
||||||
|
Ok(Ty::new_var(self.tcx(), new_var_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -614,6 +641,15 @@ fn consts(
|
|||||||
universe: self.for_universe,
|
universe: self.for_universe,
|
||||||
})
|
})
|
||||||
.vid;
|
.vid;
|
||||||
|
|
||||||
|
// See the comment for type inference variables
|
||||||
|
// for more details.
|
||||||
|
if self.infcx.next_trait_solver()
|
||||||
|
&& !self.infcx.intercrate
|
||||||
|
&& self.in_alias
|
||||||
|
{
|
||||||
|
variable_table.union(vid, new_var_id);
|
||||||
|
}
|
||||||
Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty()))
|
Ok(ty::Const::new_var(self.tcx(), new_var_id, c.ty()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TokenTreeDiagInfo {
|
pub(super) struct TokenTreeDiagInfo {
|
||||||
/// Stack of open delimiters and their spans. Used for error message.
|
/// Stack of open delimiters and their spans. Used for error message.
|
||||||
pub open_braces: Vec<(Delimiter, Span)>,
|
pub open_braces: Vec<(Delimiter, Span)>,
|
||||||
pub unmatched_delims: Vec<UnmatchedDelim>,
|
pub unmatched_delims: Vec<UnmatchedDelim>,
|
||||||
@ -21,7 +21,7 @@ pub struct TokenTreeDiagInfo {
|
|||||||
pub matching_block_spans: Vec<(Span, Span)>,
|
pub matching_block_spans: Vec<(Span, Span)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Span) -> bool {
|
pub(super) fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Span) -> bool {
|
||||||
match (sm.span_to_margin(open_sp), sm.span_to_margin(close_sp)) {
|
match (sm.span_to_margin(open_sp), sm.span_to_margin(close_sp)) {
|
||||||
(Some(open_padding), Some(close_padding)) => open_padding == close_padding,
|
(Some(open_padding), Some(close_padding)) => open_padding == close_padding,
|
||||||
_ => false,
|
_ => false,
|
||||||
@ -30,7 +30,7 @@ pub fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Span) ->
|
|||||||
|
|
||||||
// When we get a `)` or `]` for `{`, we should emit help message here
|
// When we get a `)` or `]` for `{`, we should emit help message here
|
||||||
// it's more friendly compared to report `unmatched error` in later phase
|
// it's more friendly compared to report `unmatched error` in later phase
|
||||||
pub fn report_missing_open_delim(err: &mut Diag<'_>, unmatched_delims: &[UnmatchedDelim]) -> bool {
|
fn report_missing_open_delim(err: &mut Diag<'_>, unmatched_delims: &[UnmatchedDelim]) -> bool {
|
||||||
let mut reported_missing_open = false;
|
let mut reported_missing_open = false;
|
||||||
for unmatch_brace in unmatched_delims.iter() {
|
for unmatch_brace in unmatched_delims.iter() {
|
||||||
if let Some(delim) = unmatch_brace.found_delim
|
if let Some(delim) = unmatch_brace.found_delim
|
||||||
@ -51,7 +51,7 @@ pub fn report_missing_open_delim(err: &mut Diag<'_>, unmatched_delims: &[Unmatch
|
|||||||
reported_missing_open
|
reported_missing_open
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn report_suspicious_mismatch_block(
|
pub(super) fn report_suspicious_mismatch_block(
|
||||||
err: &mut Diag<'_>,
|
err: &mut Diag<'_>,
|
||||||
diag_info: &TokenTreeDiagInfo,
|
diag_info: &TokenTreeDiagInfo,
|
||||||
sm: &SourceMap,
|
sm: &SourceMap,
|
||||||
|
@ -112,7 +112,7 @@ struct StringReader<'psess, 'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'psess, 'src> StringReader<'psess, 'src> {
|
impl<'psess, 'src> StringReader<'psess, 'src> {
|
||||||
pub fn dcx(&self) -> &'psess DiagCtxt {
|
fn dcx(&self) -> &'psess DiagCtxt {
|
||||||
&self.psess.dcx
|
&self.psess.dcx
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
use rustc_span::{symbol::kw, BytePos, Pos, Span};
|
use rustc_span::{symbol::kw, BytePos, Pos, Span};
|
||||||
|
|
||||||
#[rustfmt::skip] // for line breaks
|
#[rustfmt::skip] // for line breaks
|
||||||
pub(crate) const UNICODE_ARRAY: &[(char, &str, &str)] = &[
|
pub(super) const UNICODE_ARRAY: &[(char, &str, &str)] = &[
|
||||||
('
', "Line Separator", " "),
|
('
', "Line Separator", " "),
|
||||||
('
', "Paragraph Separator", " "),
|
('
', "Paragraph Separator", " "),
|
||||||
(' ', "Ogham Space mark", " "),
|
(' ', "Ogham Space mark", " "),
|
||||||
|
@ -1052,12 +1052,12 @@ pub(super) fn try_const_eval_resolve(
|
|||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
) -> Option<ty::Const<'tcx>> {
|
) -> Option<ty::Const<'tcx>> {
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
match self.infcx.try_const_eval_resolve(param_env, unevaluated, ty, DUMMY_SP) {
|
match self.infcx.const_eval_resolve(param_env, unevaluated, DUMMY_SP) {
|
||||||
Ok(ct) => Some(ct),
|
Ok(Some(val)) => Some(ty::Const::new_value(self.tcx(), val, ty)),
|
||||||
|
Ok(None) | Err(ErrorHandled::TooGeneric(_)) => None,
|
||||||
Err(ErrorHandled::Reported(e, _)) => {
|
Err(ErrorHandled::Reported(e, _)) => {
|
||||||
Some(ty::Const::new_error(self.tcx(), e.into(), ty))
|
Some(ty::Const::new_error(self.tcx(), e.into(), ty))
|
||||||
}
|
}
|
||||||
Err(ErrorHandled::TooGeneric(_)) => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +376,10 @@ pub fn canonical_goal_evaluation(&mut self, canonical_goal_evaluation: ProofTree
|
|||||||
(
|
(
|
||||||
DebugSolver::GoalEvaluation(goal_evaluation),
|
DebugSolver::GoalEvaluation(goal_evaluation),
|
||||||
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation),
|
DebugSolver::CanonicalGoalEvaluation(canonical_goal_evaluation),
|
||||||
) => goal_evaluation.evaluation = Some(canonical_goal_evaluation),
|
) => {
|
||||||
|
let prev = goal_evaluation.evaluation.replace(canonical_goal_evaluation);
|
||||||
|
assert_eq!(prev, None);
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,3 +239,46 @@ window.addEventListener("pageshow", ev => {
|
|||||||
setTimeout(updateSidebarWidth, 0);
|
setTimeout(updateSidebarWidth, 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Custom elements are used to insert some JS-dependent features into Rustdoc,
|
||||||
|
// because the [parser] runs the connected callback
|
||||||
|
// synchronously. It needs to be added synchronously so that nothing below it
|
||||||
|
// becomes visible until after it's done. Otherwise, you get layout jank.
|
||||||
|
//
|
||||||
|
// That's also why this is in storage.js and not main.js.
|
||||||
|
//
|
||||||
|
// [parser]: https://html.spec.whatwg.org/multipage/parsing.html
|
||||||
|
class RustdocSearchElement extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
const rootPath = getVar("root-path");
|
||||||
|
const currentCrate = getVar("current-crate");
|
||||||
|
this.innerHTML = `<nav class="sub">
|
||||||
|
<form class="search-form">
|
||||||
|
<span></span> <!-- This empty span is a hacky fix for Safari - See #93184 -->
|
||||||
|
<div id="sidebar-button" tabindex="-1">
|
||||||
|
<a href="${rootPath}${currentCrate}/all.html" title="show sidebar"></a>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
class="search-input"
|
||||||
|
name="search"
|
||||||
|
aria-label="Run search in the documentation"
|
||||||
|
autocomplete="off"
|
||||||
|
spellcheck="false"
|
||||||
|
placeholder="Type ‘S’ or ‘/’ to search, ‘?’ for more options…"
|
||||||
|
type="search">
|
||||||
|
<div id="help-button" tabindex="-1">
|
||||||
|
<a href="${rootPath}help.html" title="help">?</a>
|
||||||
|
</div>
|
||||||
|
<div id="settings-menu" tabindex="-1">
|
||||||
|
<a href="${rootPath}settings.html" title="settings">
|
||||||
|
Settings
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</nav>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.customElements.define("rustdoc-search", RustdocSearchElement);
|
||||||
|
@ -117,30 +117,9 @@
|
|||||||
<div class="sidebar-resizer"></div> {# #}
|
<div class="sidebar-resizer"></div> {# #}
|
||||||
<main> {# #}
|
<main> {# #}
|
||||||
{% if page.css_class != "src" %}<div class="width-limiter">{% endif %}
|
{% if page.css_class != "src" %}<div class="width-limiter">{% endif %}
|
||||||
<nav class="sub"> {# #}
|
{# defined in storage.js to avoid duplicating complex UI across every page #}
|
||||||
<form class="search-form"> {# #}
|
{# and because the search form only works if JS is enabled anyway #}
|
||||||
<span></span> {# This empty span is a hacky fix for Safari - See #93184 #}
|
<rustdoc-search></rustdoc-search> {# #}
|
||||||
<div id="sidebar-button" tabindex="-1"> {# #}
|
|
||||||
<a href="{{page.root_path|safe}}{{layout.krate|safe}}/all.html" title="show sidebar"></a> {# #}
|
|
||||||
</div> {# #}
|
|
||||||
<input {#+ #}
|
|
||||||
class="search-input" {#+ #}
|
|
||||||
name="search" {#+ #}
|
|
||||||
aria-label="Run search in the documentation" {#+ #}
|
|
||||||
autocomplete="off" {#+ #}
|
|
||||||
spellcheck="false" {#+ #}
|
|
||||||
placeholder="Type ‘S’ or ‘/’ to search, ‘?’ for more options…" {#+ #}
|
|
||||||
type="search"> {# #}
|
|
||||||
<div id="help-button" tabindex="-1"> {# #}
|
|
||||||
<a href="{{page.root_path|safe}}help.html" title="help">?</a> {# #}
|
|
||||||
</div> {# #}
|
|
||||||
<div id="settings-menu" tabindex="-1"> {# #}
|
|
||||||
<a href="{{page.root_path|safe}}settings.html" title="settings"> {# #}
|
|
||||||
Settings {# #}
|
|
||||||
</a> {# #}
|
|
||||||
</div> {# #}
|
|
||||||
</form> {# #}
|
|
||||||
</nav> {# #}
|
|
||||||
<section id="main-content" class="content">{{ content|safe }}</section> {# #}
|
<section id="main-content" class="content">{{ content|safe }}</section> {# #}
|
||||||
{% if page.css_class != "src" %}</div>{% endif %}
|
{% if page.css_class != "src" %}</div>{% endif %}
|
||||||
</main> {# #}
|
</main> {# #}
|
||||||
|
@ -29,6 +29,8 @@ fn check_html_file(file: &Path) -> usize {
|
|||||||
.arg("-quiet")
|
.arg("-quiet")
|
||||||
.arg("--mute-id") // this option is useful in case we want to mute more warnings
|
.arg("--mute-id") // this option is useful in case we want to mute more warnings
|
||||||
.arg("yes")
|
.arg("yes")
|
||||||
|
.arg("--new-blocklevel-tags")
|
||||||
|
.arg("rustdoc-search") // custom elements
|
||||||
.arg("--mute")
|
.arg("--mute")
|
||||||
.arg(&to_mute_s)
|
.arg(&to_mute_s)
|
||||||
.arg(file);
|
.arg(file);
|
||||||
|
@ -4,7 +4,7 @@ javascript: false
|
|||||||
|
|
||||||
go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
|
go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
|
||||||
show-text: true
|
show-text: true
|
||||||
assert-css: (".sub", {"display": "none"})
|
assert-false: ".sub"
|
||||||
|
|
||||||
// Even though JS is disabled, we should still have themes applied. Links are never black-colored
|
// Even though JS is disabled, we should still have themes applied. Links are never black-colored
|
||||||
// if styles are applied so we check that they are not.
|
// if styles are applied so we check that they are not.
|
||||||
|
@ -4,7 +4,7 @@ javascript: false
|
|||||||
go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
|
go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
|
||||||
// Since the javascript is disabled, there shouldn't be a toggle.
|
// Since the javascript is disabled, there shouldn't be a toggle.
|
||||||
wait-for-css: (".sidebar", {"display": "none"})
|
wait-for-css: (".sidebar", {"display": "none"})
|
||||||
assert-css: ("#sidebar-button", {"display": "none"})
|
assert-false: "#sidebar-button"
|
||||||
|
|
||||||
// Let's retry with javascript enabled.
|
// Let's retry with javascript enabled.
|
||||||
javascript: true
|
javascript: true
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
//@ compile-flags: -Znext-solver=coherence
|
//@ compile-flags: -Znext-solver
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct X<const FN: fn() = { || {} }>;
|
struct X<const FN: fn() = { || {} }>;
|
||||||
//~^ ERROR using function pointers as const generic parameters is forbidden
|
//~^ ERROR using function pointers as const generic parameters is forbidden
|
||||||
//~| ERROR using function pointers as const generic parameters is forbidden
|
//~| ERROR using function pointers as const generic parameters is forbidden
|
||||||
|
//~| ERROR type annotations needed
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
error[E0282]: type annotations needed
|
||||||
|
--> $DIR/const-region-infer-to-static-in-binder.rs:4:10
|
||||||
|
|
|
||||||
|
LL | struct X<const FN: fn() = { || {} }>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `{ || {} }`
|
||||||
|
|
||||||
error: using function pointers as const generic parameters is forbidden
|
error: using function pointers as const generic parameters is forbidden
|
||||||
--> $DIR/const-region-infer-to-static-in-binder.rs:4:20
|
--> $DIR/const-region-infer-to-static-in-binder.rs:4:20
|
||||||
|
|
|
|
||||||
@ -15,5 +21,6 @@ LL | struct X<const FN: fn() = { || {} }>;
|
|||||||
= note: the only supported types are integers, `bool` and `char`
|
= note: the only supported types are integers, `bool` and `char`
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0282`.
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
//@ revisions: old next
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// Generalizing an alias referencing escaping bound variables
|
||||||
|
// is hard. We previously didn't replace this alias with inference
|
||||||
|
// variables but did replace nested alias which do not reference
|
||||||
|
// any bound variables. This caused us to stall with the following
|
||||||
|
// goal, which cannot make any progress:
|
||||||
|
//
|
||||||
|
// <<T as Id>::Refl as HigherRanked>::Output<'a>
|
||||||
|
// alias-relate
|
||||||
|
// <?unconstrained as HigherRanked>::Output<'a>
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// cc trait-system-refactor-initiative#110
|
||||||
|
|
||||||
|
#![allow(unused)]
|
||||||
|
trait HigherRanked {
|
||||||
|
type Output<'a>;
|
||||||
|
}
|
||||||
|
trait Id {
|
||||||
|
type Refl: HigherRanked;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<T: Id>() -> for<'a> fn(<<T as Id>::Refl as HigherRanked>::Output<'a>) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bar<T: Id>() {
|
||||||
|
// we generalize here
|
||||||
|
let x = foo::<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,32 @@
|
|||||||
|
//@ revisions: old next
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// A minimization of an ambiguity error in `icu_provider`.
|
||||||
|
//
|
||||||
|
// cc trait-system-refactor-initiative#110
|
||||||
|
|
||||||
|
trait Yokeable<'a> {
|
||||||
|
type Output;
|
||||||
|
}
|
||||||
|
trait Id {
|
||||||
|
type Refl;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_deserialized<M: Id>() -> M
|
||||||
|
where
|
||||||
|
M::Refl: for<'a> Yokeable<'a>,
|
||||||
|
{
|
||||||
|
try_map_project::<M, _>(|_| todo!())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_map_project<M: Id, F>(_f: F) -> M
|
||||||
|
where
|
||||||
|
M::Refl: for<'a> Yokeable<'a>,
|
||||||
|
F: for<'a> FnOnce(&'a ()) -> <<M as Id>::Refl as Yokeable<'a>>::Output,
|
||||||
|
{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,51 @@
|
|||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
//@ check-pass
|
||||||
|
|
||||||
|
// A regression test for a fairly subtle issue with how we
|
||||||
|
// generalize aliases referencing higher-ranked regions
|
||||||
|
// which previously caused unexpected ambiguity errors.
|
||||||
|
//
|
||||||
|
// The explanations in the test may end up being out of date
|
||||||
|
// in the future as we may refine our approach to generalization
|
||||||
|
// going forward.
|
||||||
|
//
|
||||||
|
// cc trait-system-refactor-initiative#108
|
||||||
|
trait Trait<'a> {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Trait<'a> for () {
|
||||||
|
type Assoc = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo<T: for<'a> Trait<'a>>(x: T) -> for<'a> fn(<T as Trait<'a>>::Assoc) {
|
||||||
|
|_| ()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unconstrained<T>() -> T {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// create `?x.0` in the root universe
|
||||||
|
let mut x = unconstrained();
|
||||||
|
|
||||||
|
// bump the current universe of the inference context
|
||||||
|
let bump: for<'a, 'b> fn(&'a (), &'b ()) = |_, _| ();
|
||||||
|
let _: for<'a> fn(&'a (), &'a ()) = bump;
|
||||||
|
|
||||||
|
// create `?y.1` in a higher universe
|
||||||
|
let mut y = Default::default();
|
||||||
|
|
||||||
|
// relate `?x.0` with `for<'a> fn(<?y.1 as Trait<'a>>::Assoc)`
|
||||||
|
// -> instantiate `?x.0` with `for<'a> fn(<?y_new.0 as Trait<'a>>::Assoc)`
|
||||||
|
x = foo(y);
|
||||||
|
|
||||||
|
// Constrain `?y.1` to `()`
|
||||||
|
let _: () = y;
|
||||||
|
|
||||||
|
// `AliasRelate(<?y_new.0 as Trait<'a>>::Assoc, <() as Trait<'a>>::Assoc)`
|
||||||
|
// remains ambiguous unless we somehow constrain `?y_new.0` during
|
||||||
|
// generalization to be equal to `?y.1`, which is exactly what we
|
||||||
|
// did to fix this issue.
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
//@ revisions: old next
|
//@ revisions: old next
|
||||||
//@[next] compile-flags: -Znext-solver
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
//@ check-pass
|
//@ check-pass
|
||||||
|
|
||||||
// case 3 of https://github.com/rust-lang/trait-system-refactor-initiative/issues/8.
|
// case 3 of https://github.com/rust-lang/trait-system-refactor-initiative/issues/8.
|
||||||
|
Loading…
Reference in New Issue
Block a user