Auto merge of #95931 - matthiaskrgr:rollup-1c5zhit, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #95743 (Update binary_search example to instead redirect to partition_point) - #95771 (Update linker-plugin-lto.md to 1.60) - #95861 (Note that CI tests Windows 10) - #95875 (bootstrap: show available paths help text for aliased subcommands) - #95876 (Add a note for unsatisfied `~const Drop` bounds) - #95907 (address fixme for diagnostic variable name) - #95917 (thin_box test: import from std, not alloc) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
43998d5441
11 changed files with 157 additions and 98 deletions
|
@ -347,8 +347,7 @@ impl<'tcx> Ty<'tcx> {
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn note_and_explain_type_err(
|
pub fn note_and_explain_type_err(
|
||||||
self,
|
self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
err: &TypeError<'tcx>,
|
err: &TypeError<'tcx>,
|
||||||
cause: &ObligationCause<'tcx>,
|
cause: &ObligationCause<'tcx>,
|
||||||
sp: Span,
|
sp: Span,
|
||||||
|
@ -360,12 +359,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
ArgumentSorts(values, _) | Sorts(values) => {
|
ArgumentSorts(values, _) | Sorts(values) => {
|
||||||
match (values.expected.kind(), values.found.kind()) {
|
match (values.expected.kind(), values.found.kind()) {
|
||||||
(ty::Closure(..), ty::Closure(..)) => {
|
(ty::Closure(..), ty::Closure(..)) => {
|
||||||
db.note("no two closures, even if identical, have the same type");
|
diag.note("no two closures, even if identical, have the same type");
|
||||||
db.help("consider boxing your closure and/or using it as a trait object");
|
diag.help("consider boxing your closure and/or using it as a trait object");
|
||||||
}
|
}
|
||||||
(ty::Opaque(..), ty::Opaque(..)) => {
|
(ty::Opaque(..), ty::Opaque(..)) => {
|
||||||
// Issue #63167
|
// Issue #63167
|
||||||
db.note("distinct uses of `impl Trait` result in different opaque types");
|
diag.note("distinct uses of `impl Trait` result in different opaque types");
|
||||||
}
|
}
|
||||||
(ty::Float(_), ty::Infer(ty::IntVar(_)))
|
(ty::Float(_), ty::Infer(ty::IntVar(_)))
|
||||||
if let Ok(
|
if let Ok(
|
||||||
|
@ -374,7 +373,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
) = self.sess.source_map().span_to_snippet(sp) =>
|
) = self.sess.source_map().span_to_snippet(sp) =>
|
||||||
{
|
{
|
||||||
if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
|
if snippet.chars().all(|c| c.is_digit(10) || c == '-' || c == '_') {
|
||||||
db.span_suggestion(
|
diag.span_suggestion(
|
||||||
sp,
|
sp,
|
||||||
"use a float literal",
|
"use a float literal",
|
||||||
format!("{}.0", snippet),
|
format!("{}.0", snippet),
|
||||||
|
@ -386,30 +385,30 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let generics = self.generics_of(body_owner_def_id);
|
let generics = self.generics_of(body_owner_def_id);
|
||||||
let e_span = self.def_span(generics.type_param(expected, self).def_id);
|
let e_span = self.def_span(generics.type_param(expected, self).def_id);
|
||||||
if !sp.contains(e_span) {
|
if !sp.contains(e_span) {
|
||||||
db.span_label(e_span, "expected type parameter");
|
diag.span_label(e_span, "expected type parameter");
|
||||||
}
|
}
|
||||||
let f_span = self.def_span(generics.type_param(found, self).def_id);
|
let f_span = self.def_span(generics.type_param(found, self).def_id);
|
||||||
if !sp.contains(f_span) {
|
if !sp.contains(f_span) {
|
||||||
db.span_label(f_span, "found type parameter");
|
diag.span_label(f_span, "found type parameter");
|
||||||
}
|
}
|
||||||
db.note(
|
diag.note(
|
||||||
"a type parameter was expected, but a different one was found; \
|
"a type parameter was expected, but a different one was found; \
|
||||||
you might be missing a type parameter or trait bound",
|
you might be missing a type parameter or trait bound",
|
||||||
);
|
);
|
||||||
db.note(
|
diag.note(
|
||||||
"for more information, visit \
|
"for more information, visit \
|
||||||
https://doc.rust-lang.org/book/ch10-02-traits.html\
|
https://doc.rust-lang.org/book/ch10-02-traits.html\
|
||||||
#traits-as-parameters",
|
#traits-as-parameters",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(ty::Projection(_), ty::Projection(_)) => {
|
(ty::Projection(_), ty::Projection(_)) => {
|
||||||
db.note("an associated type was expected, but a different one was found");
|
diag.note("an associated type was expected, but a different one was found");
|
||||||
}
|
}
|
||||||
(ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p)) => {
|
(ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p)) => {
|
||||||
let generics = self.generics_of(body_owner_def_id);
|
let generics = self.generics_of(body_owner_def_id);
|
||||||
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
||||||
if !sp.contains(p_span) {
|
if !sp.contains(p_span) {
|
||||||
db.span_label(p_span, "this type parameter");
|
diag.span_label(p_span, "this type parameter");
|
||||||
}
|
}
|
||||||
let hir = self.hir();
|
let hir = self.hir();
|
||||||
let mut note = true;
|
let mut note = true;
|
||||||
|
@ -444,14 +443,14 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
note = !suggest_constraining_type_param(
|
note = !suggest_constraining_type_param(
|
||||||
self,
|
self,
|
||||||
generics,
|
generics,
|
||||||
db,
|
diag,
|
||||||
&format!("{}", proj.self_ty()),
|
&format!("{}", proj.self_ty()),
|
||||||
&path,
|
&path,
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if note {
|
if note {
|
||||||
db.note("you might be missing a type parameter or trait bound");
|
diag.note("you might be missing a type parameter or trait bound");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(ty::Param(p), ty::Dynamic(..) | ty::Opaque(..))
|
(ty::Param(p), ty::Dynamic(..) | ty::Opaque(..))
|
||||||
|
@ -459,11 +458,11 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
let generics = self.generics_of(body_owner_def_id);
|
let generics = self.generics_of(body_owner_def_id);
|
||||||
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
||||||
if !sp.contains(p_span) {
|
if !sp.contains(p_span) {
|
||||||
db.span_label(p_span, "this type parameter");
|
diag.span_label(p_span, "this type parameter");
|
||||||
}
|
}
|
||||||
db.help("type parameters must be constrained to match other types");
|
diag.help("type parameters must be constrained to match other types");
|
||||||
if self.sess.teach(&db.get_code().unwrap()) {
|
if self.sess.teach(&diag.get_code().unwrap()) {
|
||||||
db.help(
|
diag.help(
|
||||||
"given a type parameter `T` and a method `foo`:
|
"given a type parameter `T` and a method `foo`:
|
||||||
```
|
```
|
||||||
trait Trait<T> { fn foo(&self) -> T; }
|
trait Trait<T> { fn foo(&self) -> T; }
|
||||||
|
@ -489,7 +488,7 @@ impl<T> Trait<T> for X {
|
||||||
```",
|
```",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
db.note(
|
diag.note(
|
||||||
"for more information, visit \
|
"for more information, visit \
|
||||||
https://doc.rust-lang.org/book/ch10-02-traits.html\
|
https://doc.rust-lang.org/book/ch10-02-traits.html\
|
||||||
#traits-as-parameters",
|
#traits-as-parameters",
|
||||||
|
@ -499,9 +498,9 @@ impl<T> Trait<T> for X {
|
||||||
let generics = self.generics_of(body_owner_def_id);
|
let generics = self.generics_of(body_owner_def_id);
|
||||||
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
||||||
if !sp.contains(p_span) {
|
if !sp.contains(p_span) {
|
||||||
db.span_label(p_span, "this type parameter");
|
diag.span_label(p_span, "this type parameter");
|
||||||
}
|
}
|
||||||
db.help(&format!(
|
diag.help(&format!(
|
||||||
"every closure has a distinct type and so could not always match the \
|
"every closure has a distinct type and so could not always match the \
|
||||||
caller-chosen type of parameter `{}`",
|
caller-chosen type of parameter `{}`",
|
||||||
p
|
p
|
||||||
|
@ -511,12 +510,12 @@ impl<T> Trait<T> for X {
|
||||||
let generics = self.generics_of(body_owner_def_id);
|
let generics = self.generics_of(body_owner_def_id);
|
||||||
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
||||||
if !sp.contains(p_span) {
|
if !sp.contains(p_span) {
|
||||||
db.span_label(p_span, "this type parameter");
|
diag.span_label(p_span, "this type parameter");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(ty::Projection(proj_ty), _) => {
|
(ty::Projection(proj_ty), _) => {
|
||||||
self.expected_projection(
|
self.expected_projection(
|
||||||
db,
|
diag,
|
||||||
proj_ty,
|
proj_ty,
|
||||||
values,
|
values,
|
||||||
body_owner_def_id,
|
body_owner_def_id,
|
||||||
|
@ -529,19 +528,19 @@ impl<T> Trait<T> for X {
|
||||||
values.found, values.expected,
|
values.found, values.expected,
|
||||||
);
|
);
|
||||||
if !(self.suggest_constraining_opaque_associated_type(
|
if !(self.suggest_constraining_opaque_associated_type(
|
||||||
db,
|
diag,
|
||||||
&msg,
|
&msg,
|
||||||
proj_ty,
|
proj_ty,
|
||||||
values.expected,
|
values.expected,
|
||||||
) || self.suggest_constraint(
|
) || self.suggest_constraint(
|
||||||
db,
|
diag,
|
||||||
&msg,
|
&msg,
|
||||||
body_owner_def_id,
|
body_owner_def_id,
|
||||||
proj_ty,
|
proj_ty,
|
||||||
values.expected,
|
values.expected,
|
||||||
)) {
|
)) {
|
||||||
db.help(&msg);
|
diag.help(&msg);
|
||||||
db.note(
|
diag.note(
|
||||||
"for more information, visit \
|
"for more information, visit \
|
||||||
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
|
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
|
||||||
);
|
);
|
||||||
|
@ -560,7 +559,7 @@ impl<T> Trait<T> for X {
|
||||||
CyclicTy(ty) => {
|
CyclicTy(ty) => {
|
||||||
// Watch out for various cases of cyclic types and try to explain.
|
// Watch out for various cases of cyclic types and try to explain.
|
||||||
if ty.is_closure() || ty.is_generator() {
|
if ty.is_closure() || ty.is_generator() {
|
||||||
db.note(
|
diag.note(
|
||||||
"closures cannot capture themselves or take themselves as argument;\n\
|
"closures cannot capture themselves or take themselves as argument;\n\
|
||||||
this error may be the result of a recent compiler bug-fix,\n\
|
this error may be the result of a recent compiler bug-fix,\n\
|
||||||
see issue #46062 <https://github.com/rust-lang/rust/issues/46062>\n\
|
see issue #46062 <https://github.com/rust-lang/rust/issues/46062>\n\
|
||||||
|
@ -574,10 +573,10 @@ impl<T> Trait<T> for X {
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|attr| attr.has_name(sym::target_feature))
|
.filter(|attr| attr.has_name(sym::target_feature))
|
||||||
.map(|attr| attr.span);
|
.map(|attr| attr.span);
|
||||||
db.note(
|
diag.note(
|
||||||
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
|
"functions with `#[target_feature]` can only be coerced to `unsafe` function pointers"
|
||||||
);
|
);
|
||||||
db.span_labels(target_spans, "`#[target_feature]` added here");
|
diag.span_labels(target_spans, "`#[target_feature]` added here");
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -585,8 +584,7 @@ impl<T> Trait<T> for X {
|
||||||
|
|
||||||
fn suggest_constraint(
|
fn suggest_constraint(
|
||||||
self,
|
self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
msg: &str,
|
msg: &str,
|
||||||
body_owner_def_id: DefId,
|
body_owner_def_id: DefId,
|
||||||
proj_ty: &ty::ProjectionTy<'tcx>,
|
proj_ty: &ty::ProjectionTy<'tcx>,
|
||||||
|
@ -623,7 +621,7 @@ impl<T> Trait<T> for X {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.constrain_generic_bound_associated_type_structured_suggestion(
|
if self.constrain_generic_bound_associated_type_structured_suggestion(
|
||||||
db,
|
diag,
|
||||||
&trait_ref,
|
&trait_ref,
|
||||||
pred.bounds,
|
pred.bounds,
|
||||||
&assoc,
|
&assoc,
|
||||||
|
@ -642,7 +640,7 @@ impl<T> Trait<T> for X {
|
||||||
{
|
{
|
||||||
// This is type param `A` in `<A as T>::Foo`.
|
// This is type param `A` in `<A as T>::Foo`.
|
||||||
return self.constrain_generic_bound_associated_type_structured_suggestion(
|
return self.constrain_generic_bound_associated_type_structured_suggestion(
|
||||||
db,
|
diag,
|
||||||
&trait_ref,
|
&trait_ref,
|
||||||
param.bounds,
|
param.bounds,
|
||||||
&assoc,
|
&assoc,
|
||||||
|
@ -673,8 +671,7 @@ impl<T> Trait<T> for X {
|
||||||
/// fn that returns the type.
|
/// fn that returns the type.
|
||||||
fn expected_projection(
|
fn expected_projection(
|
||||||
self,
|
self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
proj_ty: &ty::ProjectionTy<'tcx>,
|
proj_ty: &ty::ProjectionTy<'tcx>,
|
||||||
values: &ExpectedFound<Ty<'tcx>>,
|
values: &ExpectedFound<Ty<'tcx>>,
|
||||||
body_owner_def_id: DefId,
|
body_owner_def_id: DefId,
|
||||||
|
@ -712,7 +709,7 @@ impl<T> Trait<T> for X {
|
||||||
// want the more general suggestion later in this method about "consider constraining
|
// want the more general suggestion later in this method about "consider constraining
|
||||||
// the associated type or calling a method that returns the associated type".
|
// the associated type or calling a method that returns the associated type".
|
||||||
let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type(
|
let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type(
|
||||||
db,
|
diag,
|
||||||
assoc.container.id(),
|
assoc.container.id(),
|
||||||
current_method_ident,
|
current_method_ident,
|
||||||
proj_ty.item_def_id,
|
proj_ty.item_def_id,
|
||||||
|
@ -720,33 +717,36 @@ impl<T> Trait<T> for X {
|
||||||
);
|
);
|
||||||
// Possibly suggest constraining the associated type to conform to the
|
// Possibly suggest constraining the associated type to conform to the
|
||||||
// found type.
|
// found type.
|
||||||
if self.suggest_constraint(db, &msg, body_owner_def_id, proj_ty, values.found)
|
if self.suggest_constraint(diag, &msg, body_owner_def_id, proj_ty, values.found)
|
||||||
|| point_at_assoc_fn
|
|| point_at_assoc_fn
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.suggest_constraining_opaque_associated_type(db, &msg, proj_ty, values.found);
|
self.suggest_constraining_opaque_associated_type(diag, &msg, proj_ty, values.found);
|
||||||
|
|
||||||
if self.point_at_associated_type(db, body_owner_def_id, values.found) {
|
if self.point_at_associated_type(diag, body_owner_def_id, values.found) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !impl_comparison {
|
if !impl_comparison {
|
||||||
// Generic suggestion when we can't be more specific.
|
// Generic suggestion when we can't be more specific.
|
||||||
if callable_scope {
|
if callable_scope {
|
||||||
db.help(&format!("{} or calling a method that returns `{}`", msg, values.expected));
|
diag.help(&format!(
|
||||||
|
"{} or calling a method that returns `{}`",
|
||||||
|
msg, values.expected
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
db.help(&msg);
|
diag.help(&msg);
|
||||||
}
|
}
|
||||||
db.note(
|
diag.note(
|
||||||
"for more information, visit \
|
"for more information, visit \
|
||||||
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
|
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if self.sess.teach(&db.get_code().unwrap()) {
|
if self.sess.teach(&diag.get_code().unwrap()) {
|
||||||
db.help(
|
diag.help(
|
||||||
"given an associated type `T` and a method `foo`:
|
"given an associated type `T` and a method `foo`:
|
||||||
```
|
```
|
||||||
trait Trait {
|
trait Trait {
|
||||||
|
@ -769,8 +769,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
/// a return type. This can occur when dealing with `TryStream` (#71035).
|
/// a return type. This can occur when dealing with `TryStream` (#71035).
|
||||||
fn suggest_constraining_opaque_associated_type(
|
fn suggest_constraining_opaque_associated_type(
|
||||||
self,
|
self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
msg: &str,
|
msg: &str,
|
||||||
proj_ty: &ty::ProjectionTy<'tcx>,
|
proj_ty: &ty::ProjectionTy<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
|
@ -790,7 +789,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);
|
let (trait_ref, assoc_substs) = proj_ty.trait_ref_and_own_substs(self);
|
||||||
|
|
||||||
self.constrain_generic_bound_associated_type_structured_suggestion(
|
self.constrain_generic_bound_associated_type_structured_suggestion(
|
||||||
db,
|
diag,
|
||||||
&trait_ref,
|
&trait_ref,
|
||||||
opaque_hir_ty.bounds,
|
opaque_hir_ty.bounds,
|
||||||
assoc,
|
assoc,
|
||||||
|
@ -806,8 +805,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
|
|
||||||
fn point_at_methods_that_satisfy_associated_type(
|
fn point_at_methods_that_satisfy_associated_type(
|
||||||
self,
|
self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
assoc_container_id: DefId,
|
assoc_container_id: DefId,
|
||||||
current_method_ident: Option<Symbol>,
|
current_method_ident: Option<Symbol>,
|
||||||
proj_ty_item_def_id: DefId,
|
proj_ty_item_def_id: DefId,
|
||||||
|
@ -854,7 +852,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
for (sp, label) in methods.into_iter() {
|
for (sp, label) in methods.into_iter() {
|
||||||
span.push_span_label(sp, label);
|
span.push_span_label(sp, label);
|
||||||
}
|
}
|
||||||
db.span_help(span, &msg);
|
diag.span_help(span, &msg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
@ -862,8 +860,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
|
|
||||||
fn point_at_associated_type(
|
fn point_at_associated_type(
|
||||||
self,
|
self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
body_owner_def_id: DefId,
|
body_owner_def_id: DefId,
|
||||||
found: Ty<'tcx>,
|
found: Ty<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
@ -887,7 +884,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
if let hir::Defaultness::Default { has_value: true } = item.defaultness
|
if let hir::Defaultness::Default { has_value: true } = item.defaultness
|
||||||
{
|
{
|
||||||
if self.type_of(item.id.def_id) == found {
|
if self.type_of(item.id.def_id) == found {
|
||||||
db.span_label(
|
diag.span_label(
|
||||||
item.span,
|
item.span,
|
||||||
"associated type defaults can't be assumed inside the \
|
"associated type defaults can't be assumed inside the \
|
||||||
trait defining them",
|
trait defining them",
|
||||||
|
@ -907,7 +904,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
for item in &items[..] {
|
for item in &items[..] {
|
||||||
if let hir::AssocItemKind::Type = item.kind {
|
if let hir::AssocItemKind::Type = item.kind {
|
||||||
if self.type_of(item.id.def_id) == found {
|
if self.type_of(item.id.def_id) == found {
|
||||||
db.span_label(item.span, "expected this associated type");
|
diag.span_label(item.span, "expected this associated type");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -927,8 +924,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
/// type is defined on a supertrait of the one present in the bounds.
|
/// type is defined on a supertrait of the one present in the bounds.
|
||||||
fn constrain_generic_bound_associated_type_structured_suggestion(
|
fn constrain_generic_bound_associated_type_structured_suggestion(
|
||||||
self,
|
self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
trait_ref: &ty::TraitRef<'tcx>,
|
trait_ref: &ty::TraitRef<'tcx>,
|
||||||
bounds: hir::GenericBounds<'_>,
|
bounds: hir::GenericBounds<'_>,
|
||||||
assoc: &ty::AssocItem,
|
assoc: &ty::AssocItem,
|
||||||
|
@ -958,15 +954,21 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
_ => return false,
|
_ => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.constrain_associated_type_structured_suggestion(db, span, assoc, assoc_substs, ty, msg)
|
self.constrain_associated_type_structured_suggestion(
|
||||||
|
diag,
|
||||||
|
span,
|
||||||
|
assoc,
|
||||||
|
assoc_substs,
|
||||||
|
ty,
|
||||||
|
msg,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a span corresponding to a bound, provide a structured suggestion to set an
|
/// Given a span corresponding to a bound, provide a structured suggestion to set an
|
||||||
/// associated type to a given type `ty`.
|
/// associated type to a given type `ty`.
|
||||||
fn constrain_associated_type_structured_suggestion(
|
fn constrain_associated_type_structured_suggestion(
|
||||||
self,
|
self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
span: Span,
|
span: Span,
|
||||||
assoc: &ty::AssocItem,
|
assoc: &ty::AssocItem,
|
||||||
assoc_substs: &[ty::GenericArg<'tcx>],
|
assoc_substs: &[ty::GenericArg<'tcx>],
|
||||||
|
@ -984,7 +986,7 @@ fn foo(&self) -> Self::T { String::new() }
|
||||||
let item_args = self.format_generic_args(assoc_substs);
|
let item_args = self.format_generic_args(assoc_substs);
|
||||||
(span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(self), item_args, ty))
|
(span.shrink_to_hi(), format!("<{}{} = {}>", assoc.ident(self), item_args, ty))
|
||||||
};
|
};
|
||||||
db.span_suggestion_verbose(span, msg, sugg, MaybeIncorrect);
|
diag.span_suggestion_verbose(span, msg, sugg, MaybeIncorrect);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
|
|
@ -1875,8 +1875,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||||
/// Returns whether to add `'static` lifetime to the suggested lifetime list.
|
/// Returns whether to add `'static` lifetime to the suggested lifetime list.
|
||||||
crate fn report_elision_failure(
|
crate fn report_elision_failure(
|
||||||
&mut self,
|
&mut self,
|
||||||
// FIXME(eddyb) rename this since it's no longer a `DiagnosticBuilder`.
|
diag: &mut Diagnostic,
|
||||||
db: &mut Diagnostic,
|
|
||||||
params: &[ElisionFailureInfo],
|
params: &[ElisionFailureInfo],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut m = String::new();
|
let mut m = String::new();
|
||||||
|
@ -1891,7 +1890,7 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||||
let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } =
|
let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } =
|
||||||
info;
|
info;
|
||||||
|
|
||||||
db.span_label(span, "");
|
diag.span_label(span, "");
|
||||||
let help_name = if let Some(ident) =
|
let help_name = if let Some(ident) =
|
||||||
parent.and_then(|body| self.tcx.hir().body(body).params[index].pat.simple_ident())
|
parent.and_then(|body| self.tcx.hir().body(body).params[index].pat.simple_ident())
|
||||||
{
|
{
|
||||||
|
@ -1923,27 +1922,27 @@ impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
db.help(
|
diag.help(
|
||||||
"this function's return type contains a borrowed value, \
|
"this function's return type contains a borrowed value, \
|
||||||
but there is no value for it to be borrowed from",
|
but there is no value for it to be borrowed from",
|
||||||
);
|
);
|
||||||
true
|
true
|
||||||
} else if elided_len == 0 {
|
} else if elided_len == 0 {
|
||||||
db.help(
|
diag.help(
|
||||||
"this function's return type contains a borrowed value with \
|
"this function's return type contains a borrowed value with \
|
||||||
an elided lifetime, but the lifetime cannot be derived from \
|
an elided lifetime, but the lifetime cannot be derived from \
|
||||||
the arguments",
|
the arguments",
|
||||||
);
|
);
|
||||||
true
|
true
|
||||||
} else if elided_len == 1 {
|
} else if elided_len == 1 {
|
||||||
db.help(&format!(
|
diag.help(&format!(
|
||||||
"this function's return type contains a borrowed value, \
|
"this function's return type contains a borrowed value, \
|
||||||
but the signature does not say which {} it is borrowed from",
|
but the signature does not say which {} it is borrowed from",
|
||||||
m
|
m
|
||||||
));
|
));
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
db.help(&format!(
|
diag.help(&format!(
|
||||||
"this function's return type contains a borrowed value, \
|
"this function's return type contains a borrowed value, \
|
||||||
but the signature does not say whether it is borrowed from {}",
|
but the signature does not say whether it is borrowed from {}",
|
||||||
m
|
m
|
||||||
|
|
|
@ -440,6 +440,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait()
|
||||||
|
&& predicate_is_const
|
||||||
|
{
|
||||||
|
err.note("`~const Drop` was renamed to `~const Destruct`");
|
||||||
|
err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details");
|
||||||
|
}
|
||||||
|
|
||||||
let explanation = if let ObligationCauseCode::MainFunctionType =
|
let explanation = if let ObligationCauseCode::MainFunctionType =
|
||||||
obligation.cause.code()
|
obligation.cause.code()
|
||||||
{
|
{
|
||||||
|
|
|
@ -2593,14 +2593,15 @@ impl<T, A: Allocator> VecDeque<T, A> {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// If you want to insert an item to a sorted deque, while maintaining
|
/// If you want to insert an item to a sorted deque, while maintaining
|
||||||
/// sort order:
|
/// sort order, consider using [`partition_point`]:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::collections::VecDeque;
|
/// use std::collections::VecDeque;
|
||||||
///
|
///
|
||||||
/// let mut deque: VecDeque<_> = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
/// let mut deque: VecDeque<_> = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
||||||
/// let num = 42;
|
/// let num = 42;
|
||||||
/// let idx = deque.binary_search(&num).unwrap_or_else(|x| x);
|
/// let idx = deque.partition_point(|&x| x < num);
|
||||||
|
/// // The above is equivalent to `let idx = deque.binary_search(&num).unwrap_or_else(|x| x);`
|
||||||
/// deque.insert(idx, num);
|
/// deque.insert(idx, num);
|
||||||
/// assert_eq!(deque, &[0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
|
/// assert_eq!(deque, &[0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -2744,6 +2745,19 @@ impl<T, A: Allocator> VecDeque<T, A> {
|
||||||
/// assert!(deque.iter().take(i).all(|&x| x < 5));
|
/// assert!(deque.iter().take(i).all(|&x| x < 5));
|
||||||
/// assert!(deque.iter().skip(i).all(|&x| !(x < 5)));
|
/// assert!(deque.iter().skip(i).all(|&x| !(x < 5)));
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// If you want to insert an item to a sorted deque, while maintaining
|
||||||
|
/// sort order:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::collections::VecDeque;
|
||||||
|
///
|
||||||
|
/// let mut deque: VecDeque<_> = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55].into();
|
||||||
|
/// let num = 42;
|
||||||
|
/// let idx = deque.partition_point(|&x| x < num);
|
||||||
|
/// deque.insert(idx, num);
|
||||||
|
/// assert_eq!(deque, &[0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
|
||||||
|
/// ```
|
||||||
#[stable(feature = "vecdeque_binary_search", since = "1.54.0")]
|
#[stable(feature = "vecdeque_binary_search", since = "1.54.0")]
|
||||||
pub fn partition_point<P>(&self, mut pred: P) -> usize
|
pub fn partition_point<P>(&self, mut pred: P) -> usize
|
||||||
where
|
where
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use alloc::boxed::ThinBox;
|
|
||||||
use core::mem::size_of;
|
use core::mem::size_of;
|
||||||
|
use std::boxed::ThinBox;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn want_niche_optimization() {
|
fn want_niche_optimization() {
|
||||||
|
|
|
@ -2331,12 +2331,13 @@ impl<T> [T] {
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// If you want to insert an item to a sorted vector, while maintaining
|
/// If you want to insert an item to a sorted vector, while maintaining
|
||||||
/// sort order:
|
/// sort order, consider using [`partition_point`]:
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
|
/// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
|
||||||
/// let num = 42;
|
/// let num = 42;
|
||||||
/// let idx = s.binary_search(&num).unwrap_or_else(|x| x);
|
/// let idx = s.partition_point(|&x| x < num);
|
||||||
|
/// // The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
|
||||||
/// s.insert(idx, num);
|
/// s.insert(idx, num);
|
||||||
/// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
|
/// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
|
||||||
/// ```
|
/// ```
|
||||||
|
@ -3743,6 +3744,17 @@ impl<T> [T] {
|
||||||
/// assert!(v[..i].iter().all(|&x| x < 5));
|
/// assert!(v[..i].iter().all(|&x| x < 5));
|
||||||
/// assert!(v[i..].iter().all(|&x| !(x < 5)));
|
/// assert!(v[i..].iter().all(|&x| !(x < 5)));
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
|
/// If you want to insert an item to a sorted vector, while maintaining
|
||||||
|
/// sort order:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
|
||||||
|
/// let num = 42;
|
||||||
|
/// let idx = s.partition_point(|&x| x < num);
|
||||||
|
/// s.insert(idx, num);
|
||||||
|
/// assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
|
||||||
|
/// ```
|
||||||
#[stable(feature = "partition_point", since = "1.52.0")]
|
#[stable(feature = "partition_point", since = "1.52.0")]
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn partition_point<P>(&self, mut pred: P) -> usize
|
pub fn partition_point<P>(&self, mut pred: P) -> usize
|
||||||
|
|
|
@ -621,9 +621,9 @@ impl<'a> Builder<'a> {
|
||||||
|
|
||||||
pub fn get_help(build: &Build, subcommand: &str) -> Option<String> {
|
pub fn get_help(build: &Build, subcommand: &str) -> Option<String> {
|
||||||
let kind = match subcommand {
|
let kind = match subcommand {
|
||||||
"build" => Kind::Build,
|
"build" | "b" => Kind::Build,
|
||||||
"doc" => Kind::Doc,
|
"doc" | "d" => Kind::Doc,
|
||||||
"test" => Kind::Test,
|
"test" | "t" => Kind::Test,
|
||||||
"bench" => Kind::Bench,
|
"bench" => Kind::Bench,
|
||||||
"dist" => Kind::Dist,
|
"dist" => Kind::Dist,
|
||||||
"install" => Kind::Install,
|
"install" => Kind::Install,
|
||||||
|
|
|
@ -136,7 +136,7 @@ able to get around this problem by setting `-Clinker=lld-link` in RUSTFLAGS
|
||||||
```sh
|
```sh
|
||||||
rustup toolchain install --profile minimal nightly
|
rustup toolchain install --profile minimal nightly
|
||||||
MINOR_VERSION=$(rustc +nightly --version | cut -d . -f 2)
|
MINOR_VERSION=$(rustc +nightly --version | cut -d . -f 2)
|
||||||
LOWER_BOUND=44
|
LOWER_BOUND=61
|
||||||
|
|
||||||
llvm_version() {
|
llvm_version() {
|
||||||
toolchain="$1"
|
toolchain="$1"
|
||||||
|
@ -179,5 +179,19 @@ The following table shows known good combinations of toolchain versions.
|
||||||
| Rust 1.44 | Clang 9 |
|
| Rust 1.44 | Clang 9 |
|
||||||
| Rust 1.45 | Clang 10 |
|
| Rust 1.45 | Clang 10 |
|
||||||
| Rust 1.46 | Clang 10 |
|
| Rust 1.46 | Clang 10 |
|
||||||
|
| Rust 1.47 | Clang 11 |
|
||||||
|
| Rust 1.48 | Clang 11 |
|
||||||
|
| Rust 1.49 | Clang 11 |
|
||||||
|
| Rust 1.50 | Clang 11 |
|
||||||
|
| Rust 1.51 | Clang 11 |
|
||||||
|
| Rust 1.52 | Clang 12 |
|
||||||
|
| Rust 1.53 | Clang 12 |
|
||||||
|
| Rust 1.54 | Clang 12 |
|
||||||
|
| Rust 1.55 | Clang 12 |
|
||||||
|
| Rust 1.56 | Clang 13 |
|
||||||
|
| Rust 1.57 | Clang 13 |
|
||||||
|
| Rust 1.58 | Clang 13 |
|
||||||
|
| Rust 1.59 | Clang 13 |
|
||||||
|
| Rust 1.60 | Clang 14 |
|
||||||
|
|
||||||
Note that the compatibility policy for this feature might change in the future.
|
Note that the compatibility policy for this feature might change in the future.
|
||||||
|
|
|
@ -31,18 +31,20 @@ All tier 1 targets with host tools support the full standard library.
|
||||||
target | notes
|
target | notes
|
||||||
-------|-------
|
-------|-------
|
||||||
`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.2, glibc 2.17+) [^missing-stack-probes]
|
`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.2, glibc 2.17+) [^missing-stack-probes]
|
||||||
`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+)
|
`i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support]
|
||||||
`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+)
|
`i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support]
|
||||||
`i686-unknown-linux-gnu` | 32-bit Linux (kernel 2.6.32+, glibc 2.11+)
|
`i686-unknown-linux-gnu` | 32-bit Linux (kernel 2.6.32+, glibc 2.11+)
|
||||||
`x86_64-apple-darwin` | 64-bit macOS (10.7+, Lion+)
|
`x86_64-apple-darwin` | 64-bit macOS (10.7+, Lion+)
|
||||||
`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+)
|
`x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+) [^windows-support]
|
||||||
`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+)
|
`x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+) [^windows-support]
|
||||||
`x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 2.6.32+, glibc 2.11+)
|
`x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 2.6.32+, glibc 2.11+)
|
||||||
|
|
||||||
[^missing-stack-probes]: Stack probes support is missing on
|
[^missing-stack-probes]: Stack probes support is missing on
|
||||||
`aarch64-unknown-linux-gnu`, but it's planned to be implemented in the near
|
`aarch64-unknown-linux-gnu`, but it's planned to be implemented in the near
|
||||||
future. The implementation is tracked on [issue #77071][77071].
|
future. The implementation is tracked on [issue #77071][77071].
|
||||||
|
|
||||||
|
[^windows-support]: Only Windows 10 currently undergoes automated testing. Earlier versions of Windows rely on testing and support from the community.
|
||||||
|
|
||||||
[77071]: https://github.com/rust-lang/rust/issues/77071
|
[77071]: https://github.com/rust-lang/rust/issues/77071
|
||||||
|
|
||||||
## Tier 1
|
## Tier 1
|
||||||
|
|
|
@ -302,23 +302,13 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
|
||||||
|
|
||||||
impl<'a> Clean<Option<WherePredicate>> for ty::PolyTraitPredicate<'a> {
|
impl<'a> Clean<Option<WherePredicate>> for ty::PolyTraitPredicate<'a> {
|
||||||
fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> {
|
fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> {
|
||||||
// `T: ~const Drop` is not equivalent to `T: Drop`, and we don't currently document `~const` bounds
|
|
||||||
// because of its experimental status, so just don't show these.
|
|
||||||
// `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
|
// `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
|
||||||
if self.skip_binder().constness == ty::BoundConstness::ConstIfConst
|
if self.skip_binder().constness == ty::BoundConstness::ConstIfConst
|
||||||
&& [cx.tcx.lang_items().drop_trait(), cx.tcx.lang_items().destruct_trait()]
|
&& Some(self.skip_binder().def_id()) == cx.tcx.lang_items().destruct_trait()
|
||||||
.iter()
|
|
||||||
.any(|tr| *tr == Some(self.skip_binder().def_id()))
|
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(bootstrap)]
|
|
||||||
{
|
|
||||||
// FIXME: remove `lang_items().drop_trait()` from above logic,
|
|
||||||
// as well as the comment about `~const Drop` because it was renamed to `Destruct`.
|
|
||||||
}
|
|
||||||
|
|
||||||
let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
|
let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
|
||||||
Some(WherePredicate::BoundPredicate {
|
Some(WherePredicate::BoundPredicate {
|
||||||
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
|
ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Test that we do not currently display `~const` in rustdoc
|
// Test that we do not currently display `~const` in rustdoc
|
||||||
// as that syntax is currently provisional; `~const Drop` has
|
// as that syntax is currently provisional; `~const Destruct` has
|
||||||
// no effect on stable code so it should be hidden as well.
|
// no effect on stable code so it should be hidden as well.
|
||||||
//
|
//
|
||||||
// To future blessers: make sure that `const_trait_impl` is
|
// To future blessers: make sure that `const_trait_impl` is
|
||||||
|
@ -8,6 +8,8 @@
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
#![crate_name = "foo"]
|
#![crate_name = "foo"]
|
||||||
|
|
||||||
|
use std::marker::Destruct;
|
||||||
|
|
||||||
pub struct S<T>(T);
|
pub struct S<T>(T);
|
||||||
|
|
||||||
// @!has foo/trait.Tr.html '//pre[@class="rust trait"]/code/a[@class="trait"]' '~const'
|
// @!has foo/trait.Tr.html '//pre[@class="rust trait"]/code/a[@class="trait"]' '~const'
|
||||||
|
@ -20,22 +22,36 @@ pub trait Tr<T> {
|
||||||
// @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
|
// @!has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where"]' '~const'
|
||||||
// @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
|
// @has - '//div[@id="method.a"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
|
||||||
#[default_method_body_is_const]
|
#[default_method_body_is_const]
|
||||||
fn a<A: ~const Clone>() where Option<A>: ~const Clone {}
|
fn a<A: ~const Clone + ~const Destruct>()
|
||||||
|
where
|
||||||
|
Option<A>: ~const Clone + ~const Destruct,
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]' '~const'
|
// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]' '~const'
|
||||||
// @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Clone'
|
// @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/a[@class="trait"]' 'Clone'
|
||||||
// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where"]' '~const'
|
// @!has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where"]' '~const'
|
||||||
// @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' ': Clone'
|
// @has - '//section[@id="impl-Tr%3CT%3E"]/h3[@class="code-header in-band"]/span[@class="where fmt-newline"]' ': Clone'
|
||||||
impl<T: ~const Clone> const Tr<T> for T where Option<T>: ~const Clone {
|
impl<T: ~const Clone + ~const Destruct> const Tr<T> for T
|
||||||
fn a<A: ~const Clone>() where Option<A>: ~const Clone {}
|
where
|
||||||
|
Option<T>: ~const Clone + ~const Destruct,
|
||||||
|
{
|
||||||
|
fn a<A: ~const Clone + ~const Destruct>()
|
||||||
|
where
|
||||||
|
Option<A>: ~const Clone + ~const Destruct,
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @!has foo/fn.foo.html '//pre[@class="rust fn"]/code/a[@class="trait"]' '~const'
|
// @!has foo/fn.foo.html '//pre[@class="rust fn"]/code/a[@class="trait"]' '~const'
|
||||||
// @has - '//pre[@class="rust fn"]/code/a[@class="trait"]' 'Clone'
|
// @has - '//pre[@class="rust fn"]/code/a[@class="trait"]' 'Clone'
|
||||||
// @!has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' '~const'
|
// @!has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' '~const'
|
||||||
// @has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' ': Clone'
|
// @has - '//pre[@class="rust fn"]/code/span[@class="where fmt-newline"]' ': Clone'
|
||||||
pub const fn foo<F: ~const Clone>() where Option<F>: ~const Clone {
|
pub const fn foo<F: ~const Clone + ~const Destruct>()
|
||||||
|
where
|
||||||
|
Option<F>: ~const Clone + ~const Destruct,
|
||||||
|
{
|
||||||
F::a()
|
F::a()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +60,10 @@ impl<T> S<T> {
|
||||||
// @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
|
// @has - '//section[@id="method.foo"]/h4[@class="code-header"]/a[@class="trait"]' 'Clone'
|
||||||
// @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const'
|
// @!has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where"]' '~const'
|
||||||
// @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
|
// @has - '//section[@id="method.foo"]/h4[@class="code-header"]/span[@class="where fmt-newline"]' ': Clone'
|
||||||
pub const fn foo<B: ~const Clone>() where B: ~const Clone {
|
pub const fn foo<B: ~const Clone + ~const Destruct>()
|
||||||
|
where
|
||||||
|
B: ~const Clone + ~const Destruct,
|
||||||
|
{
|
||||||
B::a()
|
B::a()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue